Author: wmb
Date: 2008-01-28 12:41:18 +0100 (Mon, 28 Jan 2008)
New Revision: 795
Modified:
cpu/x86/pc/biosload/rmenter.fth
dev/ide/generic.fth
dev/video/common/textmode.fth
dev/video/controlr/vga.fth
Log:
BIOSload version - another checkpoint of BIOS gateway code.
Modified: cpu/x86/pc/biosload/rmenter.fth
===================================================================
--- cpu/x86/pc/biosload/rmenter.fth 2008-01-28 04:19:49 UTC (rev 794)
+++ cpu/x86/pc/biosload/rmenter.fth 2008-01-28 11:41:18 UTC (rev 795)
@@ -4,14 +4,36 @@
: seg:off> ( offset segment -- linear ) 4 lshift + ;
: seg:off@ ( adr -- linear ) dup w@ swap wa1+ w@ seg:off> ;
[then]
+: >off ( linear -- 16-bit offset ) >seg:off drop ;
+h# 9.0000 constant rm-base
+h# 9.0000 constant rm-avail
+h# ff00 constant rm-base2
+h# 9.fc00 constant 'ebda \ Extended BIOS Data Area, which we co-opt for our real-mode workspace
+'ebda constant new-gdt-pa
+
[ifdef] syslinux-loaded
h# 8 constant rm-cs
h# 18 constant rm-ds
h# 20 constant pm-cs
h# 28 constant pm-ds
-: fix-gdt ;
+: fix-gdt
+ \ 16-bit 64K code segment starting at rm-base
+ rm-base lbsplit ( adr.0 adr.1 adr.2 adr.3 )
+ 2swap h# ffff -rot bwjoin wljoin ( adr.2 adr.3 desc.lo )
+ -rot ( desc.lo adr.2 adr.3 )
+ >r h# 9a 0 r> bljoin ( desc.lo desc.hi )
+ gdtr@ drop rm-cs + d! ( )
+
+ \ 16-bit 64K data segment starting at rm-base
+ rm-base lbsplit ( adr.0 adr.1 adr.2 adr.3 )
+ 2swap h# ffff -rot bwjoin wljoin ( adr.2 adr.3 desc.lo )
+ -rot ( desc.lo adr.2 adr.3 )
+ >r h# 93 0 r> bljoin ( desc.lo desc.hi )
+ gdtr@ drop rm-ds + d! ( )
+;
[then]
+
[ifdef] preof-loaded
h# 38 constant rm-cs
h# 30 constant rm-ds
@@ -26,31 +48,28 @@
[then]
-h# 0.0000 constant rm-base
-: +rm ( offset -- adr ) rm-base + ;
+: +rm ( offset -- adr ) rm-base + rm-base2 + ;
-\ The real-mode stack pointer will start here
-h# f00 +rm constant 'rm-stack
-\ h# ef0 +rm constant 'rm-dispatch
-
\ Place for the initial registers upon entry to real mode.
-h# f00 +rm constant 'rm-regs
+\ The real-mode stack pointer will start here, so the registers
+\ can be loaded by popping the stack
+h# 00 +rm constant 'rm-regs
\ (00) 4 * 2: GS,FS,ES,DS
\ (08) 8 * 4: EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX
\ (28) 1 * 4: CS:IP of return address
\ (2c) 1 * 2: flags
\ size is 2e
-h# f30 +rm constant 'rm-idt \ For loading RM IDT with LIDT
-h# f36 +rm constant 'rm-int \ Incoming interrupt number
-h# f38 +rm constant 'rm-sp \ SS:SP For loading RM SP with LSS
-h# f3c +rm constant 'pm-sp \ Save/restore area for PM SP
-h# f40 +rm constant 'pm-gdt \ For loading PM GDT with LGDT
-h# f48 +rm constant 'pm-idt \ For loading PM IDT with LGDT
+h# 30 +rm constant 'rm-idt \ For loading RM IDT with LIDT
+h# 36 +rm constant 'rm-int \ Incoming interrupt number
+h# 38 +rm constant 'rm-sp \ SS:SP For loading RM SP with LSS
+h# 3c +rm constant 'pm-sp \ Save/restore area for PM SP
+h# 40 +rm constant 'pm-gdt \ For loading PM GDT with LGDT
+h# 48 +rm constant 'pm-idt \ For loading PM IDT with LGDT
-h# f50 +rm constant 'rm-to-pm
-h# fa0 +rm constant 'pm-to-rm
-h# ff0 +rm constant 'rm-enter
+h# 50 +rm constant 'rm-to-pm
+h# a0 +rm constant 'pm-to-rm
+h# f0 +rm constant 'rm-enter
: caller-regs 'rm-sp seg:off@ ;
struct
@@ -104,6 +123,8 @@
: rm-set-cf rm-flags@ 1 or rm-flags! ;
: rm-clr-cf rm-flags@ 1 invert and rm-flags! ;
+: rm-int@ 'rm-int w@ h# ff and ;
+
true value show-rm-int?
: noshow false to show-rm-int? ;
variable save-eax
@@ -111,7 +132,7 @@
true to show-rm-int? caller-regs >rm-eax @ save-eax !
;
: showint
- ." INT " 'rm-int w@ . save-eax @ wbsplit ." AH " . ." AL " . cr
+ ." INT " rm-int@ . save-eax @ wbsplit ." AH " . ." AL " . cr
;
: ?showint show-rm-int? if showint then ;
@@ -121,19 +142,21 @@
/vectors buffer: saved-ofw-vectors
-\ 80ff0 is the target address of the interrupt vector
+\ 90ff0 is the target address of the interrupt vector
\ We use different segment:offset representations of that address in
\ the vector table, so the handler code can determine the vector
\ number by inspecting the code segment register value
-\ 00: 8000:0ff0
-\ 01: 8001:0fe0
+\ 00: nn00:mff0
+\ 01: nn01:mfe0
\ ...
-\ ff: 80ff:0000
+\ ff: nnff:m000
: grab-rm-vector ( vector# -- )
>r
- h# ff0 r@ 4 lshift - r@ /l* w! \ Set offset
- rm-base 4 rshift r@ + r> /l* wa1+ w! \ Set segment
+ 'rm-enter lwsplit ( low16 high16 )
+ swap r@ 4 lshift - swap ( vec.offset high16 )
+ d# 12 lshift r@ + wljoin ( vec.seg:off )
+ r> /l* l! \ Set segment
;
: ungrab-rm-vector ( vector# -- )
saved-rm-vectors over la+ l@ ( vector# value )
@@ -163,20 +186,27 @@
\ (low) GS,FS,ES,DS (high)
\ CS from interrupt vector, which is the interrupt number
- cs: 'rm-int #) pop \ Save interrupt vector CS, i.e. the int#
-
cli \ This is unnecessary since we got here from an INT
cs push ds pop
- sp 'rm-sp #) mov
- ss 'rm-sp 2+ #) mov
+ 'rm-int >off #) pop \ Save interrupt vector CS, i.e. the int#
- op: 'pm-gdt #) lgdt
+ sp 'rm-sp >off #) mov
+ ss 'rm-sp 2+ >off #) mov
+
+ op: 'pm-gdt >off #) lgdt
cr0 ax mov 1 # al or ax cr0 mov \ Enter protected mode
- here 5 + rm-to-pm - 'rm-to-pm + pm-cs #) far jmp
+ \ The assembler gyrations here are subtle. We need to jump to an address
+ \ that may be larger than 16 bits, but we are currently running from a
+ \ 16-bit code segment. So we have to tell the assembler to go into
+ \ "protected mode" (a misnomer; that assembler directive really means
+ \ to assemble for the 32-bit instruction set) so it will put down a
+ \ ptr16:32 operand. But we also need the op: prefix, so the processor
+ \ will interpret the operand as a ptr16:32 instead of a ptr16:16
protected-mode
+ op: here 7 + rm-to-pm - 'rm-to-pm + pm-cs #) far jmp
ax ax xor pm-ds # al mov ax ds mov ax es mov ax gs mov ax gs mov ax ss mov
'rm-idt #) sidt
@@ -227,7 +257,7 @@
cli
sp sp xor
- 'pm-to-rm rm-cs #) far jmp
+ 'pm-to-rm >off rm-cs #) far jmp
end-code
\ This is the common target of all the real-mode interrupt vectors.
@@ -251,8 +281,7 @@
: move-gdt ( -- )
gdtr@ 1+ ( gdt-adr gdt-len )
-\ dup h# 10 + alloc-mem h# f + h# f invert and ( gdt-adr gdt-len new-gdt )
- h# 900
+ new-gdt-pa ( gdt-adr gdt-len new-gdt-adr )
swap 2dup 2>r move 2r> ( new-gdt gdt-len )
1- gdtr!
@@ -270,7 +299,7 @@
: regs>bios ( -- )
caller-regs bios-regs d# 40 move
rm-flags@ bios-flags l!
- 'rm-int w@ /l* @ bios-target !
+ rm-int@ /l* @ bios-target !
;
: bios>regs ( -- )
bios-regs caller-regs d# 40 move
@@ -304,7 +333,7 @@
h# 11 grab-rm-vector \ Sysinfo
h# 12 grab-rm-vector \ Low memory size
h# 13 grab-rm-vector \ Disk I/O
-\ h# 15 grab-rm-vector \ Various system stuff
+ h# 15 grab-rm-vector \ Various system stuff
h# 16 grab-rm-vector \ Keyboard
h# 1a grab-rm-vector \ PCI BIOS
[else]
@@ -327,7 +356,7 @@
prep-rm
'rm-regs h# 2e erase ( pc )
'rm-regs h# 28 + seg:off! ( )
- 'rm-stack 'rm-sp seg:off! \ Initial stack pointer below regs
+ 'rm-regs 'rm-sp seg:off! \ Initial stack pointer must be below regs
;
: !font ( adr -- )
@@ -335,8 +364,9 @@
h# 10 rm-cx! h# 18 rm-dx!
;
: get-font ( -- )
+ noshow
rm-al@ h# 30 = if
- ." Int 10 get-font called - BH = " rm-bh@ . cr
+\ ." Int 10 get-font called - BH = " rm-bh@ . cr
rm-bh@ case
\ These numbers are cheats, pointing into the VIA BIOS
2 of h# c69e0 !font endof
@@ -346,6 +376,7 @@
6 of h# c77e0 !font endof
7 of h# c77e0 !font
h# 10 ungrab-rm-vector
+h# 15 ungrab-rm-vector
endof
( default ) ." Unsupported get font - BH = " dup . cr rm-set-cf
endcase
@@ -574,12 +605,12 @@
[then]
create memdescs
- h# 0. d, h# a0000. d, 1 l, \ 0
-\ h# a0000. d, h# 60000. d, 2 l, \ 14
- h# f0000. d, h# 10000. d, 2 l, \ 14
- h# 100000. d, 0. d, 1 l, \ 28
-\ 0. d, 0. d, 2 l, \ 3c
- h# ffff0000. d, h# 10000. d, 2 l, \ 40
+ h# 0. d, rm-avail 0 d, 1 l, \ 0
+\ h# rm-avail 0 d, h# 60000. d, 2 l, \ 14
+ h# f0000. d, h# 10000. d, 2 l, \ 14
+ h# 100000. d, 0. d, 1 l, \ 28
+\ 0. d, 0. d, 2 l, \ 3c
+ h# ffff0000. d, h# 10000. d, 2 l, \ 40
here memdescs - constant /memdescs
: system-memory-map ( -- )
@@ -648,12 +679,15 @@
rm-clr-cf
rm-ah@ case
h# 91 of noshow 0 rm-ah! endof \ "pause" while waiting for I/O
+noop
h# 53 of apm endof
h# 86 of rm-dx@ rm-cx@ wljoin us endof \ Delay microseconds
h# 8a of memory-limit h# 400.0000 - 0 max /1k lwsplit rm-dx! rm-ax! endof
h# 88 of h# fffc rm-ax! endof \ Extended memory - at least 64 MB
h# c0 of get-conf endof
- h# c1 of rm-set-cf h# 86 rm-ah! endof
+ \ We use the extended BIOS data area as our workspace when loaded from another BIOS
+\ h# c1 of rm-set-cf h# 86 rm-ah! endof \ No extended BIOS data area
+ h# c1 of 'ebda 4 rshift caller-regs >rm-es w! endof \ Segment address of extended BIOS data area
h# c2 of handle-mouse endof
h# e8 of bigmem-int endof
( default ) rm-set-cf
@@ -661,10 +695,11 @@
endcase
;
-h# 4800 value the-key
+0 value the-key
: poll-key ( -- false | scan,ascii true )
the-key ?dup if true exit then
+ d# 50 ms \ I don't know why this is necessary, but without it, you don't see the key
0 " get-scancode" kbd-ih $call-method if ( scancode )
dup h# 80 and if ( scancode )
\ Discard release events and escapes (e0)
@@ -708,6 +743,7 @@
0 of get-keystroke endof
1 of poll-keystroke endof
2 of 0 rm-al! endof \ Claim that no shift keys are active
+ 5 of rm-cx@ to the-key endof \ Put keystroke in buffer
( bit 7:sysrq 6:capslock 5:numlock 4:scrlock 3:ralt 2:rctrl 1:lalt 0:lctrl )
( default ) ." Keyboard INT called with AH = " dup . cr
endcase
@@ -751,6 +787,7 @@
: int-1a ( -- )
rm-ah@ case
h# 0 of get-timer-ticks noshow endof
+\ h# 4 of rm-clr-cf get-rtc-date endof \ ch century cl year dh month dl day
h# b1 of pcibios endof
( default ) ." Unimplemented INT 1a - AH = " dup . cr rm-set-cf
endcase
@@ -758,19 +795,27 @@
: handle-bios-call ( -- )
snap-int
- 'rm-int w@ case
+ rm-int@ case
h# 10 of video-int endof
h# 11 of sysinfo-int endof
h# 13 of noshow disk-int endof
h# 16 of keyboard-int endof
h# 15 of system-int endof
- h# 12 of h# a0000 /1k rm-ax! endof \ Low memory size
+ h# 12 of rm-avail /1k rm-ax! endof \ Low memory size
h# 1a of int-1a endof
+ h# 18 of ." Entering Open Firmware" cr interact endof
+ h# 19 of ." Rebooting" cr bye endof
( default ) ." Interrupt " dup . cr interact
endcase
?showint
;
+: get-mbr
+ " /pci/ide@0" open-dev >r
+ h# 7c00 h# 3f 1 " read-blocks" r@ $call-method 1 <> abort" Didn't read MBR"
+ r> close-dev
+;
: rm-go ( -- )
+ get-mbr
usb-quiet
\ Load boot image at 7c00
h# 7c00 rm-init-program
@@ -782,11 +827,6 @@
label xx h# 99 # al mov al h# 80 # out begin again end-code
here xx - constant /xx
: put-xx ( adr -- ) xx swap /xx move ;
-: get-mbr
- " /pci/ide@0" open-dev >r
- h# 7c00 h# 3f 1 " read-blocks" r@ $call-method .
- r> close-dev
-;
: .lreg ( adr -- adr' ) 4 - dup l@ 9 u.r ;
: .wreg ( adr -- adr' ) 2 - dup w@ 5 u.r ;
: .caller-regs ( -- )
Modified: dev/ide/generic.fth
===================================================================
--- dev/ide/generic.fth 2008-01-28 04:19:49 UTC (rev 794)
+++ dev/ide/generic.fth 2008-01-28 11:41:18 UTC (rev 795)
@@ -202,10 +202,17 @@
over 0= if 2drop 2drop 0 exit then
- >r dup >r r-#secs! ( addr block# ) ( R: input? #blks )
- lblk>cyl-head-sect ( addr cyl# head# sect# )
- r-sector! drive r-head! r-cyl! r> r> ( addr #blks input? )
- if rblocks else wblocks then ( actual# | error )
+ >r dup >r r-#secs! ( addr block# ) ( R: input? #blks )
+ /lba if ( addr block# ) ( R: input? #blks )
+ lbsplit ( addr 0-7 8-15 16-23 24-32 )
+ \ 4, when shifted with drive, sets the LBA bit
+ h# f and drive 4 or r-head! ( addr 0-7 8-15 16-23 )
+ bwjoin r-cyl! r-sector! ( addr R: input? #blks )
+ else ( addr block# ) ( R: input? #blks )
+ lblk>cyl-head-sect ( addr cyl# head# sect# )
+ r-sector! drive r-head! r-cyl! ( addr #blks input? R: input? #blks )
+ then
+ r> r> if rblocks else wblocks then ( actual# | error )
dup 0= if
." Failed to transfer any blocks" cr
@@ -244,7 +251,8 @@
scratchbuf 3 wa+ le-w@ /heads!
scratchbuf 6 wa+ le-w@ /secs!
- /cyls h# 3fff u>= if
+\ /cyls h# 3fff u>= if
+ scratchbuf d# 49 wa+ w@ h# 200 and if \ LBA
scratchbuf d# 60 wa+ le-w@
scratchbuf d# 61 wa+ le-w@
wljoin /lba!
Modified: dev/video/common/textmode.fth
===================================================================
--- dev/video/common/textmode.fth 2008-01-28 04:19:49 UTC (rev 794)
+++ dev/video/common/textmode.fth 2008-01-28 11:41:18 UTC (rev 795)
@@ -16,7 +16,7 @@
: next-string ( table-adr -- table-adr' adr len ) count 2dup + -rot ;
-: set-mode ( table -- )
+: set-vga-mode ( table -- )
palette-off
dup c@ misc! 1+
@@ -129,11 +129,12 @@
: fill-attrs ( len value -- )
ega rot 2* bounds do dup i 1+ c! 2 +loop drop
;
-: pc-font ( -- )
- write-font
- default-font ( 2>r ) >r >r ( adr width +-height advance r: min,#glyphs )
+defer pc-font ' default-font to pc-font
+: load-vga-font ( -- )
+ pc-font ( 2>r ) >r >r ( adr width +-height advance r: min,#glyphs )
1 <> rot 8 > or over 0>= or
if true " Incompatible font" type abort then ( adr -height )
+ write-font
negate swap ( 2r> ) r> r> bounds ?do ( height adr )
2dup ega i h# 20 * + rot move ( height adr )
over + ( height adr' )
@@ -141,6 +142,7 @@
2drop ( )
write-text
;
+
create ega-colors
" "(00 00 00 00 00 aa 00 aa 00 00 aa aa)" $,
" "(aa 00 00 aa 00 aa aa aa 00 aa aa aa)" $,
@@ -166,16 +168,17 @@
: text-mode3 ( -- )
io-base -1 = if map-io-regs then
- mode2+/3 set-mode
+ mode2+/3 set-vga-mode
ext-textmode
\ h# c00b.8000 0 h# 8200.0000 h# 8000 " map-in" $call-parent to ega
h# 000b.8000 0 h# 8200.0000 h# 8000 " map-in" $call-parent to ega
- pc-font
+ load-vga-font
#text-rows #text-columns * dup bl fill-text 7 fill-attrs
[ifdef] strict-ega
ega-colors 0 d# 64 (set-colors)
[then]
;
+
\ LICENSE_BEGIN
\ Copyright (c) 2006 FirmWorks
\
Modified: dev/video/controlr/vga.fth
===================================================================
--- dev/video/controlr/vga.fth 2008-01-28 04:19:49 UTC (rev 794)
+++ dev/video/controlr/vga.fth 2008-01-28 11:41:18 UTC (rev 795)
@@ -1,11 +1,13 @@
\ See license at end of file
purpose: Generic VGA functions
+hex
+
\ reset attribute address flip-flop
: reset-attr-addr ( -- ) 3da ( input-status1 ) pc@ drop ;
: video-mode! ( b -- ) reset-attr-addr 03c0 pc! ;
-: attr! ( b index -- ) 03c0 pc! 03c0 pc! ;
+: attr! ( b index -- ) reset-attr-addr 03c0 pc! 03c0 pc! ;
: attr@ ( index -- b )
reset-attr-addr 03c0 pc! 03c1 pc@ reset-attr-addr
;
@@ -58,12 +60,15 @@
['] vga-plt! to plt!
['] vga-rindex! to rindex!
['] vga-windex! to windex!
+[ifdef] rs@
['] noop to rs@
['] 2drop to rs!
+[then]
+[ifdef] idac@
['] noop to idac@
['] 2drop to idac!
+[then]
;
-use-vga-dac
: palette-off ( -- ) 0 video-mode! ;
: palette-on ( -- ) 20 video-mode! ;
@@ -130,7 +135,13 @@
;
: hsync-on ( -- ) crt-table drop 4 + c@ 4 crt! ; \ Set hsync position
-: vga-video-on ( -- ) palette-on hsync-on ; ' vga-video-on to video-on
+: vga-video-on ( -- ) palette-on hsync-on ;
+
+: use-vga
+ use-vga-dac
+ ['] vga-video-on to video-on
+;
+
\ LICENSE_BEGIN
\ Copyright (c) 2006 FirmWorks
\