[OpenBIOS] r794 - cpu/x86/pc/biosload
svn at openbios.org
svn at openbios.org
Mon Jan 28 05:19:49 CET 2008
Author: wmb
Date: 2008-01-28 05:19:49 +0100 (Mon, 28 Jan 2008)
New Revision: 794
Modified:
cpu/x86/pc/biosload/callbios.fth
cpu/x86/pc/biosload/fw.bth
cpu/x86/pc/biosload/rmenter.fth
Log:
BIOSload version - checkpoint of BIOS gateway code.
Modified: cpu/x86/pc/biosload/callbios.fth
===================================================================
--- cpu/x86/pc/biosload/callbios.fth 2008-01-28 04:18:50 UTC (rev 793)
+++ cpu/x86/pc/biosload/callbios.fth 2008-01-28 04:19:49 UTC (rev 794)
@@ -9,42 +9,41 @@
\ We assume that we can use memory from h# 200 to h# 3ff
-\ Bounce buffer at h# 90000
-
h# 8 constant rm-code-desc
h# 18 constant rm-data-desc
h# 20 constant pm-code-desc
h# 28 constant pm-data-desc
-h# 002 constant rm-flagval \ Flags for IRET
+h# 002 constant bios-flagval \ Flags for IRET
\ Low-memory addresses
-h# 200 constant rm-go \ Real mode enter code
-h# 280 constant rm-return \ Real mode return code
-h# 300 constant rm-idt \ For loading RM IDT with LIDT
-h# 308 constant rm-sp \ For loading RM SP with LSS
+h# 200 constant 'bios-call \ Real mode enter code
+h# 280 constant 'bios-ret \ Real mode return code
+h# 300 constant 'bios-idt \ For loading RM IDT with LIDT
+h# 308 constant 'bios-sp \ For loading RM SP with LSS
h# 30c constant pm-sp-save \ Save/restore area for PM SP
h# 310 constant pm-gdt-save \ For loading PM GDT with LGDT
h# 318 constant pm-idt-save \ For loading PM IDT with LIDT
-h# 3c0 constant rm-regs \ Real-mode register buffer (in/out)
-rm-regs constant rm-gs
-rm-gs wa1+ constant rm-fs
-rm-fs wa1+ constant rm-es
-rm-es wa1+ constant rm-ds
-rm-ds wa1+ constant rm-di
-rm-di la1+ constant rm-si
-rm-si la1+ constant rm-bp
-rm-bp la1+ constant rm-xx \ Would be stack pointer
-rm-xx la1+ constant rm-bx
-rm-bx la1+ constant rm-dx
-rm-dx la1+ constant rm-cx
-rm-cx la1+ constant rm-ax
-rm-ax la1+ constant rm-flags
-rm-flags la1+ constant rm-target \ Full pointer for RM call target address
-rm-target la1+ constant rm-retloc \ Full pointer to rm-return
-rm-retloc la1+ constant rm-rflags \ Flags in case of return via IRET
-label rmint-enter
+h# 3c0 constant bios-regs \ Real-mode register buffer (in/out)
+bios-regs constant bios-gs
+bios-gs wa1+ constant bios-fs
+bios-fs wa1+ constant bios-es
+bios-es wa1+ constant bios-ds
+bios-ds wa1+ constant bios-di \ offset decimal 8
+bios-di la1+ constant bios-si
+bios-si la1+ constant bios-bp
+bios-bp la1+ constant bios-xx \ Would be stack pointer
+bios-xx la1+ constant bios-bx
+bios-bx la1+ constant bios-dx
+bios-dx la1+ constant bios-cx
+bios-cx la1+ constant bios-ax
+bios-ax la1+ constant bios-flags \ offset decimal 40
+bios-flags la1+ constant bios-target \ Full pointer for RM call target address
+bios-target la1+ constant bios-retloc \ Full pointer to 'bios-ret
+bios-retloc la1+ constant bios-rflags \ Flags in case of return via IRET
+
+label bios-call
real-mode
\ This must be copied to low memory
@@ -54,25 +53,25 @@
pm-gdt-save #) sgdt \ So we can get back
pm-idt-save #) sidt \ So we can get back
- rm-idt #) lidt
+ 'bios-idt #) lidt
cr0 ax mov h# fe # al and ax cr0 mov \ Enter real mode
- here 5 + rmint-enter - rm-go + 0 #) far jmp \ Jump to set cs
+ here 5 + bios-call - 'bios-call + 0 #) far jmp \ Jump to set cs
\ Now we are running in real mode; fix segments again
cs ax mov ax ds mov ax es mov ax fs mov ax gs mov
- rm-sp #) sp lss
+ 'bios-sp #) sp lss
- \ Load the 16-bit registers from the rm-regs area
+ \ Load the 16-bit registers from the bios-regs area
gs pop fs pop es pop ds pop op: popa op: popf
far ret \ Now we are running the real-mode target code
end-code
-here rmint-enter - constant /rmint-enter
+here bios-call - constant /bios-call
-label rmint-exit
- rm-target # sp mov \ Set the stack pointer to the top of the rm reg area
+label bios-ret
+ bios-target # sp mov \ Set the stack pointer to the top of the rm reg area
\ Copy the real-mode registers to the buffer
op: pushf op: pusha ds push es push fs push gs push
@@ -83,7 +82,7 @@
op: pm-gdt-save #) lgdt
cr0 ax mov 1 # al or ax cr0 mov
- here 5 + rmint-exit - rm-return + pm-code-desc #) far jmp
+ here 5 + bios-ret - 'bios-ret + pm-code-desc #) far jmp
protected-mode
@@ -94,10 +93,10 @@
popf
popa
c;
-here rmint-exit - constant /rmint-exit
+here bios-ret - constant /bios-ret
\ Must set up the registers area with register values and the target address
-code rm-call ( -- )
+code }bios ( -- )
pusha
pushf
@@ -105,108 +104,130 @@
cld
cli
sp sp xor
- rm-go rm-code-desc #) far jmp
+ 'bios-call rm-code-desc #) far jmp
c;
: >seg:off ( linear -- offset segment ) lwsplit d# 12 lshift ;
: seg:off! ( linear adr -- ) >r >seg:off r@ 2+ w! r> w! ;
+: seg:off> ( offset segment -- linear ) 4 lshift + ;
+: seg:off@ ( adr -- linear ) dup w@ swap wa1+ w@ seg:off> ;
0 value bios-prepped?
: ?prep-bios-call ( -- )
bios-prepped? if exit then true to bios-prepped?
- rmint-enter rm-go /rmint-enter move
- rmint-exit rm-return /rmint-exit move
- h# ffff rm-idt w!
- 0 rm-idt 2+ l!
- rm-regs rm-sp seg:off! \ Setup real-mode full pointer for lss
- rm-return rm-retloc seg:off! \ Setup return address full pointer
- rm-flagval rm-retloc 4 + w! \ Flags for return
+ bios-call 'bios-call /bios-call move
+ bios-ret 'bios-ret /bios-ret move
+ h# ffff 'bios-idt w!
+ 0 'bios-idt 2+ l!
+ bios-regs 'bios-sp seg:off! \ Setup real-mode full pointer for lss
+ 'bios-ret bios-retloc seg:off! \ Setup return address full pointer
+ bios-flagval bios-retloc 4 + w! \ Flags for return
;
-: dr
- ." ax: " rm-ax ? 2 spaces
- ." bx: " rm-bx ? 2 spaces
- ." cx: " rm-cx ? 2 spaces
- ." dx: " rm-dx ? 2 spaces
- ." bp: " rm-bp ? 2 spaces
- ." si: " rm-si ? 2 spaces
- ." di: " rm-di ? 2 spaces
+: .bios-regs
+ ." ax: " bios-ax ? 2 spaces
+ ." bx: " bios-bx ? 2 spaces
+ ." cx: " bios-cx ? 2 spaces
+ ." dx: " bios-dx ? 2 spaces
+ ." bp: " bios-bp ? 2 spaces
+ ." si: " bios-si ? 2 spaces
+ ." di: " bios-di ? 2 spaces
+ cr
+ ." ds: " bios-ds w@ . 2 spaces
+ ." es: " bios-es w@ . 2 spaces
+ ." fs: " bios-fs w@ . 2 spaces
+ ." gs: " bios-gs w@ . 2 spaces
+ ." flags: " bios-flags ?
+ cr
;
-: { ( int# -- ) ?prep-bios-call rm-regs d# 44 erase 4 * @ rm-target ! ;
-: } rm-call ;
+: bios{ ( int# -- ) ?prep-bios-call bios-regs d# 44 erase 4 * @ bios-target ! ;
-: ax rm-ax ! ;
-: ah rm-ax 1+ c! ;
-: al rm-ax c! ;
-: bx rm-bx l! ;
-: cx rm-cx l! ;
-: dx rm-dx l! ;
-: cf@ rm-flags @ 1 and ;
-: es:di >seg:off rm-es w! rm-di l! ;
+: ax bios-ax ! ;
+: ah bios-ax 1+ c! ;
+: al bios-ax c! ;
+: bx bios-bx l! ;
+: cx bios-cx l! ;
+: dx bios-dx l! ;
+: cf@ bios-flags @ 1 and ;
+: es:di >seg:off bios-es w! bios-di l! ;
+
+\ Video - INT 10
: video-mode ( mode# -- )
- d# 55 set-tick-limit h# 10 { 3 al bx } d# 10 set-tick-limit
+ d# 55 set-tick-limit h# 10 bios{ 3 al bx }bios d# 10 set-tick-limit
;
: text-mode 3 video-mode ;
: 1024x768x8 h# 105 video-mode ;
: 1024x768x16 h# 116 video-mode ;
-: apm-connect16 h# 15 { h# 5302 ax 0 bx } ;
-: apm-power-off apm-connect16 h# 15 { h# 5307 ax 1 bx 3 cx } ;
+: apm-connect16 h# 15 bios{ h# 5302 ax 0 bx }bios ;
+: apm-power-off apm-connect16 h# 15 bios{ h# 5307 ax 1 bx 3 cx }bios ;
+
+\ Memory map - INT 15
: bios-memsize ( -- n )
- h# 15 { h# e801 ax }
- rm-ax @ h# 400 * rm-bx @ h# 10000 * + h# 100000 +
+ h# 15 bios{ h# e801 ax }bios
+ bios-ax @ h# 400 * bios-bx @ h# 10000 * + h# 100000 +
;
: .bios-memory-map ( -- )
0
begin ( continuation )
- h# 15 { bx h# e820 ax h# 10000 es:di d# 20 cx " PAMS" drop @ dx }
- rm-flags @ 1 and abort" Not supported"
- rm-cx @
- h# 10000 rm-cx @ bounds ?do i @ 9 u.r 4 +loop cr
- rm-bx @ ( continuation' )
+ h# 15 bios{ bx h# e820 ax h# 10000 es:di d# 20 cx " PAMS" drop @ dx }bios
+ bios-flags @ 1 and abort" Not supported"
+ h# 10000 bios-cx @ bounds ?do i @ 9 u.r 4 +loop cr
+ bios-bx @ ( continuation' )
?dup 0= until
;
-: bios-config-b@ ( adr -- b ) lwsplit h# 1a { h# b108 ax bx rm-di ! } rm-cx @ ;
-: bios-config-w@ ( adr -- w ) lwsplit h# 1a { h# b109 ax bx rm-di ! } rm-cx @ ;
-: bios-config-l@ ( adr -- l ) lwsplit h# 1a { h# b10a ax bx rm-di ! } rm-cx @ ;
-: bios-config-b! ( b adr -- ) lwsplit h# 1a { h# b10b ax bx rm-di ! rm-cx ! } ;
-: bios-config-w! ( w adr -- ) lwsplit h# 1a { h# b10c ax bx rm-di ! rm-cx ! } ;
-: bios-config-l! ( l adr -- ) lwsplit h# 1a { h# b10d ax bx rm-di ! rm-cx ! } ;
-: disk-status ( -- stat ) h# 13 { h# 0100 ax } rm-ax @ ;
+
+\ PCI BIOS - INT 1A
+: (bios-config@) ( adr axval -- n )
+ h# 1a bios{ ax lwsplit bx bios-di ! }bios bios-cx @
+;
+: (bios-config!) ( n adr axval -- )
+ h# 1a bios{ ax lwsplit bx bios-di ! bios-cx ! }bios
+;
+
+: bios-config-b@ ( adr -- b ) h# b108 (bios-config@) ;
+: bios-config-w@ ( adr -- w ) h# b109 (bios-config@) ;
+: bios-config-l@ ( adr -- l ) h# b10a (bios-config@) ;
+: bios-config-b! ( b adr -- ) h# b10b (bios-config!) ;
+: bios-config-w! ( w adr -- ) h# b10c (bios-config!) ;
+: bios-config-l! ( l adr -- ) h# b10d (bios-config!) ;
+
+\ Disk access - INT 13
+: disk-status ( -- stat ) h# 13 bios{ h# 0100 ax }bios bios-ax @ ;
+
0 value #sects
0 value #cyls
0 value #heads
: get-drive-params ( -- )
- h# 13 { 8 ah h# 80 dx }
- rm-flags @ 1 and if true exit then
- rm-cx @ wbsplit ( cl ch )
- over h# 3f and to #sects ( cl ch )
- swap 6 rshift bwjoin 1+ to #cyls ( )
- rm-dx @ 8 rshift 1+ to #heads ( )
+ h# 13 bios{ 8 ah h# 80 dx }bios
+ bios-flags @ 1 and if true exit then
+ bios-cx @ wbsplit ( cl ch )
+ over h# 3f and to #sects ( cl ch )
+ swap 6 rshift bwjoin 1+ to #cyls ( )
+ bios-dx @ 8 rshift 1+ to #heads ( )
;
: #drive-sectors ( -- n )
- h# 13 { h# 15 ah h# 80 dx }
- rm-dx @ rm-cx @ wljoin
+ h# 13 bios{ h# 15 ah h# 80 dx }bios
+ bios-dx @ bios-cx @ wljoin
;
-: reset-disks ( -- ) h# 13 { 0 ah h# 80 dx } ;
-: reset-hard-disks ( -- ) h# 13 { h# 0d ah h# 80 dx } ;
-: do-rw ( sector1 cyl0 head0 drive0 #sectors ah-val -- )
- h# 13 { ah al ( sector1 cyl0 head0 drive0 )
- swap bwjoin dx ( sector1 cyl0 )
- wbsplit ( sector1 cyl.lo cyl.hi )
- 6 lshift rot or ( cyl.lo cyl.hi|sector )
+: reset-disks ( -- ) h# 13 bios{ 0 ah h# 80 dx }bios ;
+: reset-hard-disks ( -- ) h# 13 bios{ h# 0d ah h# 80 dx }bios ;
+: bios-rw ( sector1 head0 cyl0 drive0 #sectors ah-val -- )
+ h# 13 bios{ ah al ( sector1 head0 cyl0 drive0 )
+ rot bwjoin dx ( sector1 cyl0 )
+ wbsplit ( sector1 cyl.lo cyl.hi )
+ 6 lshift rot or ( cyl.lo cyl.hi|sector )
swap bwjoin cx
- h# 10000 >seg:off rm-es w! bx
- }
+ h# 10000 >seg:off bios-es w! bx
+ }bios
;
-: read-sectors ( sector1 cyl0 head0 drive0 #sectors -- ) 2 do-rw ;
-: write-sectors ( sector1 cyl0 head0 drive0 #sectors -- ) 3 do-rw ;
+: bios-read-sectors ( sector1 head0 cyl0 drive0 #sectors -- ) 2 bios-rw ;
+: bios-write-sectors ( sector1 head0 cyl0 drive0 #sectors -- ) 3 bios-rw ;
-: lbn>sch ( lbn -- sector cyl head )
- #sects /mod swap 1+ swap ( sector rem )
- #heads /mod ( sector head cyl )
- dup #cyls > abort" LBN out of range"
- swap ( sector cyl head )
+: lbn>shc ( lbn -- sector head cyl )
+ #sects /mod swap 1+ swap ( sector rem )
+ #heads /mod ( sector head cyl )
+ dup #cyls > abort" LBN out of range" ( sector head cyl )
;
-: lbn-read-sectors ( lbn drive #sectors -- ) 2>r lbn>sch 2r> read-sectors ;
-: lbn-write-sectors ( lbn drive #sectors -- ) 2>r lbn>sch 2r> write-sectors ;
+: lbn-read-sectors ( lbn drive #sectors -- ) 2>r lbn>shc 2r> bios-read-sectors ;
+: lbn-write-sectors ( lbn drive #sectors -- ) 2>r lbn>shc 2r> bios-write-sectors ;
Modified: cpu/x86/pc/biosload/fw.bth
===================================================================
--- cpu/x86/pc/biosload/fw.bth 2008-01-28 04:18:50 UTC (rev 793)
+++ cpu/x86/pc/biosload/fw.bth 2008-01-28 04:19:49 UTC (rev 794)
@@ -206,7 +206,7 @@
;
fload ${BP}/cpu/x86/pc/biosload/usb.fth
-\ fload ${BP}/cpu/x86/pc/biosload/callbios.fth
+fload ${BP}/cpu/x86/pc/biosload/callbios.fth
fload ${BP}/cpu/x86/pc/biosload/rmenter.fth
\ false to stand-init-debug?
@@ -275,7 +275,7 @@
warning on
only forth also definitions
- install-alarm
+\ install-alarm
#line off
@@ -323,6 +323,7 @@
.( Saving fw.img ...)
" fw.img" RAMbase save-abs-rom cr
+
\ LICENSE_BEGIN
\ Copyright (c) 2006 FirmWorks
\
Modified: cpu/x86/pc/biosload/rmenter.fth
===================================================================
--- cpu/x86/pc/biosload/rmenter.fth 2008-01-28 04:18:50 UTC (rev 793)
+++ cpu/x86/pc/biosload/rmenter.fth 2008-01-28 04:19:49 UTC (rev 794)
@@ -1,3 +1,4 @@
+[ifndef] >seg:off
: >seg:off ( linear -- offset segment ) lwsplit d# 12 lshift ;
: seg:off! ( linear adr -- ) >r >seg:off r@ wa1+ w! r> w! ;
: seg:off> ( offset segment -- linear ) 4 lshift + ;
@@ -2,2 +3,3 @@
: seg:off@ ( adr -- linear ) dup w@ swap wa1+ w@ seg:off> ;
+[then]
@@ -27,8 +29,11 @@
h# 0.0000 constant rm-base
: +rm ( offset -- adr ) rm-base + ;
+\ 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.
-\ The real-mode stack pointer will start here
h# f00 +rm constant 'rm-regs
\ (00) 4 * 2: GS,FS,ES,DS
\ (08) 8 * 4: EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX
@@ -97,8 +102,25 @@
: rm-flags! caller-regs >rm-flags w! ;
: rm-set-cf rm-flags@ 1 or rm-flags! ;
-: rm-clr-cf rm-flags@ 1 or rm-flags! ;
+: rm-clr-cf rm-flags@ 1 invert and rm-flags! ;
+true value show-rm-int?
+: noshow false to show-rm-int? ;
+variable save-eax
+: snap-int
+ true to show-rm-int? caller-regs >rm-eax @ save-eax !
+;
+: showint
+ ." INT " 'rm-int w@ . save-eax @ wbsplit ." AH " . ." AL " . cr
+;
+: ?showint show-rm-int? if showint then ;
+
+h# 80 constant /vectors
+
+/vectors buffer: saved-rm-vectors
+/vectors buffer: saved-ofw-vectors
+
+
\ 80ff0 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
@@ -108,13 +130,29 @@
\ ...
\ ff: 80ff:0000
+: 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
+;
+: ungrab-rm-vector ( vector# -- )
+ saved-rm-vectors over la+ l@ ( vector# value )
+ swap /l* l!
+;
: make-vector-table ( -- )
- h# 100 0 do
- h# ff0 i 4 lshift - i /l* w! \ Set offset
- rm-base 4 rshift i + i /l* wa1+ w! \ Set segment
- loop
+ h# 100 0 do i grab-rm-vector loop
;
+label timer-off
+ real-mode
+ ax push
+ h# 21 # al in
+ 1 # al or
+ al h# 21 # out
+ ax pop
+ iret
+end-code
+
label rm-to-pm
real-mode
@@ -205,40 +243,123 @@
end-code
here rm-enter - constant /rm-enter
-h# 400 buffer: saved-rm-vectors
+: restore-vector ( int# -- )
+ saved-rm-vectors over la+ l@ swap /l* l!
+;
0 value rm-prepped?
+: 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
+
+ swap 2dup 2>r move 2r> ( new-gdt gdt-len )
+ 1- gdtr!
+;
+0 value kbd-ih
+
+: bios-vectors ( -- )
+ 0 saved-ofw-vectors /vectors move
+ saved-rm-vectors 0 /vectors move
+;
+: ofw-vectors ( -- )
+\ 0 saved-ofw-vectors /vectors move
+ saved-ofw-vectors 0 /vectors move
+;
+: regs>bios ( -- )
+ caller-regs bios-regs d# 40 move
+ rm-flags@ bios-flags l!
+ 'rm-int w@ /l* @ bios-target !
+;
+: bios>regs ( -- )
+ bios-regs caller-regs d# 40 move
+ bios-flags l@ rm-flags!
+;
+: use-bios ( -- )
+ bios-vectors
+ ?prep-bios-call
+ regs>bios
+ }bios
+ bios>regs
+ ofw-vectors
+;
+
: prep-rm ( -- )
rm-prepped? if exit then true to rm-prepped?
fix-gdt
- 0 saved-rm-vectors h# 400 move
- make-vector-table
+ move-gdt
+
rm-enter 'rm-enter /rm-enter move
rm-to-pm 'rm-to-pm /rm-to-pm move
pm-to-rm 'pm-to-rm /pm-to-rm move
+ 0 saved-rm-vectors /vectors move
+
+[ifdef] syslinux-loaded
+ 7 h# 1.0004 config-w!
+
+ h# 10 grab-rm-vector \ Video
+ 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# 16 grab-rm-vector \ Keyboard
+ h# 1a grab-rm-vector \ PCI BIOS
+[else]
+ make-vector-table
+
+ saved-rm-vectors 8 la+ l@ 0 8 la+ l! \ Use BIOS timer tick handler
+ saved-rm-vectors h# 1c la+ l@ 0 h# 1c la+ l! \ Timer handler chain
+[then]
+
+\ \ Set up a rudimentary handler for the ISA timer
+\ timer-off 'rm-timer-off /rm-timer-off move
+\ 'rm-timer-off 0 8 la+ seg:off!
+
h# ffff 'rm-idt w! 0 'rm-idt wa1+ l! \ Limit and base
+
+ " keyboard" open-dev to kbd-ih
;
: rm-init-program ( pc -- )
prep-rm
'rm-regs h# 2e erase ( pc )
'rm-regs h# 28 + seg:off! ( )
- 'rm-regs 'rm-sp seg:off! \ Initial stack pointer below regs
+ 'rm-stack 'rm-sp seg:off! \ Initial stack pointer below regs
;
+: !font ( adr -- )
+ >seg:off caller-regs >rm-es w! caller-regs >rm-ebp l!
+ h# 10 rm-cx! h# 18 rm-dx!
+;
: get-font ( -- )
rm-al@ h# 30 = if
." 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
+ 3 of h# c6138 !font endof
+ 4 of h# c6538 !font endof
+ 5 of h# c69e0 !font endof
+ 6 of h# c77e0 !font endof
+ 7 of h# c77e0 !font
+h# 10 ungrab-rm-vector
+endof
+ ( default ) ." Unsupported get font - BH = " dup . cr rm-set-cf
+ endcase
else
." Int 10 set-font called" cr
then
;
-: video-int ( -- )
+: set-cursor ( -- ) rm-dh@ rm-dl@ ( row column ) 2drop ;
+
+: video-int ( -- ) \ INT 10
rm-ah@ case
h# 0 of ( rm-al@ set-video-mode ) endof \ Set mode - Should blank the screen
+ h# 2 of set-cursor endof
h# a of rm-al@ emit endof \ Write character
h# e of rm-al@ emit endof \ Write character
h# 11 of get-font endof \ get or set font
@@ -248,13 +369,29 @@
( default ) ." Unimplemented video int - AH = " dup . cr rm-set-cf
endcase
;
-: sysinfo-int ( -- ) h# 26 rm-ax! ;
+: bios-video-int debug-me use-bios ;
+: sysinfo-int ( -- ) \ INT 11
+ \ h# 4226 caller-regs >rm-eax ! \ to report 1 parallel and 1 serial port
+ h# 26 caller-regs >rm-eax ! \ 32 bits
+;
+
0 value disk-ih
: disk-read-sectors ( adr sector# #sectors -- #read )
+noshow
+\ ." Read " 2 pick . over . dup . ." -- "
+\ over h# 8b74aaa = if debug-me then
" read-blocks" disk-ih $call-method
+\ dup . cr
;
+: disk-write-sectors ( adr sector# #sectors -- #read )
+\ ." Write " 2 pick . over . dup . ." -- "
+\ over h# 8b74aaa = if debug-me then
+ " write-blocks" disk-ih $call-method
+\ dup . cr
+;
+
0 [if]
h# 200 constant /sector
: disk-seek ( sector# -- error? )
@@ -274,8 +411,9 @@
rm-dl@ h# 80 <> if rm-set-cf 7 rm-ah! true exit then
disk-ih if false exit then
\ " disk:0" open-dev to disk-ih
- " /ide at 0" open-dev to disk-ih
+ " /pci/ide at 0" open-dev to disk-ih
disk-ih dup 0= if rm-set-cf h# aa rm-ah! then
+ false
;
: read-sectors ( -- )
check-drive if exit then
@@ -292,13 +430,15 @@
\ rm-bx@ caller-regs >rm-es w@ seg:off> rm-al@ ( adr #sectors )
\ disk-read rm-al!
;
+: drive-sectors ( -- n ) " #blocks" disk-ih $call-method ;
: drive-params ( -- )
check-drive if exit then
\ " size" disk-ih $call-method ( d.#bytes )
\ /sector um/mod nip ( #sectors )
- " #blocks" disk-ih $call-method ( #sectors )
+ drive-sectors ( #sectors )
h# 3f / ( #tracks )
h# ff / 1- ( maxcyl ) \ Max 255 heads is traditional
+\ dup ." MAXCYL " . cr
wbsplit ( maxcyl.lo maxcyl.hi )
3 min 6 lshift h# 3f or rm-cl! ( maxcyl.lo ) \ High cyl, max sector
rm-ch! ( ) \ Low byte of max cylinder
@@ -307,16 +447,33 @@
rm-clr-cf
;
+: ds:si ( -- adr )
+ caller-regs >rm-esi w@ caller-regs >rm-ds w@ seg:off>
+;
: lba-read ( -- )
check-drive if exit then
- caller-regs >rm-esi w@ caller-regs >rm-ds w@ seg:off> ( packet-adr )
- >r r@ 4 + seg:off@ r@ 8 + l@ r@ 2+ w@ disk-read-sectors r> 2+ w!
+ ds:si ( packet-adr )
+ >r r@ 4 + seg:off@ r@ 8 + l@ r@ 2+ w@ ( adr sector# #sectors )
+\ ." LBA "
+ disk-read-sectors r> 2+ w!
\ dup 8 + l@ ( packet-adr sector# )
\ disk-seek if drop exit then ( packet-adr )
\ dup 4 + seg:off@ over 2+ w@ ( packet-adr adr #sectors )
\ disk-read
\ swap 2+ w!
;
+: lba-write ( -- )
+ check-drive if exit then
+ ds:si ( packet-adr )
+ >r r@ 4 + seg:off@ r@ 8 + l@ r@ 2+ w@ ( adr sector# #sectors )
+\ ." LBA "
+ disk-write-sectors r> 2+ w!
+\ dup 8 + l@ ( packet-adr sector# )
+\ disk-seek if drop exit then ( packet-adr )
+\ dup 4 + seg:off@ over 2+ w@ ( packet-adr adr #sectors )
+\ disk-read
+\ swap 2+ w!
+;
: check-disk-extensions ( -- )
check-drive if 0 rm-bx! exit then
@@ -324,13 +481,42 @@
h# aa55 rm-bx!
h# 20 rm-ah! 1 rm-cx!
;
+: ext-get-drive-params ( -- )
+ check-drive if exit then
+ 0 rm-ah!
+ ds:si >r ( adr )
+ r@ 2 + h# 0e erase \ CHS info not valid
+ drive-sectors r@ h# 10 + l! 0 r@ h# 14 + l! \ Total #sectors
+ h# 200 r@ h# 18 + w! \ Sector len
+ h# 1a ( written-length )
+ r@ w@ h# 1e >= if
+ -1 r@ h# 1a + l! \ No EDD
+ 4 + ( written-length' )
+ then ( written-length )
+ r@ w@ h# 20 >= if ( written-length )
+ 0 r@ h# 1e + w! \ Ensure that device path info not interpreted
+ \ Don't claim these bytes
+ then ( written-length )
+ r> w! \ Number of bytes written
+ rm-clr-cf
+;
+: get-disk-type ( -- )
+ check-drive if exit then
+ 3 rm-ah!
+ drive-sectors lwsplit rm-cx! rm-dx!
+ rm-clr-cf
+;
+
: disk-int ( -- ) \ INT 13 handler
rm-ah@ case
- h# 02 of read-sectors endof
- h# 08 of drive-params endof
+ h# 02 of noshow read-sectors endof
+ h# 08 of drive-params endof
+ h# 15 of get-disk-type endof
h# 41 of check-disk-extensions endof
- h# 42 of lba-read endof
+ h# 42 of lba-read endof
+ h# 43 of lba-write endof
+ h# 48 of ext-get-drive-params endof
( default ) ." Unsupported disk INT 13 - AH = " dup . cr
endcase
;
@@ -354,11 +540,74 @@
dup h# 100.0000 min h# 10.0000 - 0 max /1k dup rm-ax! rm-cx!
h# 100.0000 - 0 max d# 16 rshift dup rm-bx! rm-dx!
;
+: allmem ( -- n )
+ " /memory" find-package 0= abort" No /memory node" ( phandle )
+ " reg" rot get-package-property abort" No available property" ( $ )
+ decode-int drop get-encoded-int h# 10.0000 round-up
+;
+
+0 [if]
+Entry:
+ EBX Continuation value
+ ES:DI Address of Address Range Descriptor
+ ECX Length of Address Range Descriptor (=> 20 bytes)
+ EDX "SMAP" signature
+Exit:
+ Carry 0 = E820 Supported
+ EAX "SMAP" signature
+ ES:DI Same value as entry
+ ECX Length of actual reported information in bytes
+ EBX Continuation value
+ Structure of Address Range Descriptor:
+ Bytes 0-3 Low 32 bits of Base Address
+ Bytes 4-7 High 32 bits of Base Address
+ Bytes 8-11 Low 32 bits of Length in bytes
+ Bytes 12-15 High 32 bits of Length in bytes
+ Bytes 16-20 Type of Address Range:
+ 1 = AddressRangeMemory, available to OS
+ 2 = AddressRangeReserved, not available
+ 3 = AddressRangeACPI, available to OS
+ 4 = AddressRangeNVS, not available to OS
+ Other = Not defined, not available
+
+d.base d.len l.type
+[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
+here memdescs - constant /memdescs
+
+: system-memory-map ( -- )
+ caller-regs >rm-edx @ caller-regs >rm-eax !
+ caller-regs >rm-ebx @ ?dup 0= if
+ memory-limit h# 100000 - memdescs h# 30 + l!
+\ memory-limit memdescs h# 3c + l!
+\ allmem memory-limit - memdescs h# 44 + l!
+ memdescs
+ then ( adr )
+
+ dup memdescs /memdescs + = if
+ drop
+ 0 caller-regs >rm-ecx !
+ exit
+ then
+
+ dup caller-regs >rm-edi w@ caller-regs >rm-es w@ seg:off> ( adr dst )
+ caller-regs >rm-ecx @ move ( adr )
+ caller-regs >rm-ecx @ + caller-regs >rm-ebx ! ( ) \ Continuation
+ rm-clr-cf
+;
+
: bigmem-int ( -- )
rm-clr-cf
rm-al@ case
h# 01 of bigmem-16bit endof
-\ h# 20 of system-memory-map endof
+ h# 20 of system-memory-map endof
\ h# 81 of pm-system-memory-map endof
( default ) rm-set-cf
." Unsupported Bigmem int 15 AH=e8 AL=" dup . cr
@@ -370,38 +619,94 @@
rm-set-cf h# 86 rm-ah!
;
-create sysconf 8 w, h# fc c, 1 c, 0 c, h# 70 c, 0 c, 0 c,
+\ System configure
+create sysconf
+ 8 w, \ 8 bytes following
+ h# fc c, \ model
+ 1 c, \ Submodel
+ 0 c, \ BIOS rev
+ h# 74 c, \ Feature - second 8259, RTC, INT 9 calls INT 15/4F, extended BIOS area
+ 0 c,
+ 0 c,
+ 0 c,
+ 0 c,
+
: get-conf ( -- )
sysconf 'rm-regs 8 move
'rm-regs >seg:off 0 caller-regs >rm-es w! rm-bx!
+ 0 rm-ax!
;
+: handle-mouse ( -- )
+ rm-al@ case
+ 1 of rm-clr-cf endof \ Reset mouse
+ ( default ) ." Unsupported mouse INT 15 AH c2 AL " dup . cr rm-set-cf
+ endcase
+;
+
: system-int ( -- ) \ INT 15 handler
+ rm-clr-cf
rm-ah@ case
+ h# 91 of noshow 0 rm-ah! endof \ "pause" while waiting for I/O
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
+ h# c2 of handle-mouse endof
h# e8 of bigmem-int endof
( default ) rm-set-cf
." Unsupported INT 15 AH=" dup . cr
endcase
;
-: poll-key ( -- )
- key? if
- key rm-al! 0 rm-ah! \ ASCII in AL, scancode in AH
+h# 4800 value the-key
+
+: poll-key ( -- false | scan,ascii true )
+ the-key ?dup if true exit then
+ 0 " get-scancode" kbd-ih $call-method if ( scancode )
+ dup h# 80 and if ( scancode )
+ \ Discard release events and escapes (e0)
+ drop false ( false )
+ else
+ dup " scancode->char" kbd-ih $call-method 0= if 0 then ( scancode ascii )
+ dup h# 80 and if drop 0 then \ Don't return e.g. 9B for arrows
+ swap bwjoin to the-key
+ the-key true
+ then
+ else
+ false
+ then
+;
+
+0 value polled?
+: poll-keystroke ( -- )
+ noshow
+ polled? 0= if ." ? " then
+ true to polled?
+ poll-key if ( scancode,ascii )
+ rm-ax!
rm-flags@ h# 40 invert and rm-flags!
else
rm-flags@ h# 40 or rm-flags!
then
;
+: get-keystroke ( -- )
+ noshow
-: keyboard-int ( -- ) \ INT 15 handler
+ begin poll-key until ( scancode,ascii )
+ 0 to the-key
+ rm-ax!
+
+ rm-al@ [char] q = if debug-me then
+ false to polled?
+;
+
+: keyboard-int ( -- ) \ INT 16 handler
rm-ah@ case
- 1 of poll-key endof
+ 0 of get-keystroke endof
+ 1 of poll-keystroke endof
2 of 0 rm-al! endof \ Claim that no shift keys are active
( 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
@@ -417,9 +722,9 @@
h# 201 rm-bx! \ Version 2.1
1 rm-cl! \ Number of last PCI bus - XXX get this from PCI node
;
-: pcibios ( -- )
+: pcibios ( -- ) \ INT 1a
rm-clr-cf
- rm-ah@ case
+ rm-al@ case
h# 01 of pcibios-installed endof
\ h# 02 of find-pci-device ( cx:devid dx:vendid si:index -> bh:bus# bl:devfn ) endof
\ h# 03 of find-pci-class-code ( ecx:0,classcode si:index -> bh:bus# bl:devfn ) endof
@@ -434,7 +739,7 @@
\ h# 0f of set-pci-int endof
( default ) h# 81 rm-ah! rm-set-cf
- ." Unimplemented PCI BIOS INT - AH = " dup . cr
+ ." Unimplemented PCI BIOS INT 1a AH b1 - AL = " dup . cr
endcase
;
@@ -445,30 +750,28 @@
: int-1a ( -- )
rm-ah@ case
- h# 0 of get-timer-ticks endof
+ h# 0 of get-timer-ticks noshow endof
h# b1 of pcibios endof
- ( default ) ." Unimplemented INT 1a - AH = " dup . rm-set-cf
+ ( default ) ." Unimplemented INT 1a - AH = " dup . cr rm-set-cf
endcase
;
-: showint
- ." INT " 'rm-int w@ . ." AH " rm-ah@ . ." AL " rm-al@ . cr
-;
-
: handle-bios-call ( -- )
+ snap-int
'rm-int w@ case
h# 10 of video-int endof
h# 11 of sysinfo-int endof
- h# 13 of disk-int endof
-showint
+ 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# 15 of system-int endof
- h# 16 of keyboard-int endof
h# 1a of int-1a endof
( default ) ." Interrupt " dup . cr interact
endcase
+ ?showint
;
: rm-go ( -- )
+ usb-quiet
\ Load boot image at 7c00
h# 7c00 rm-init-program
begin
@@ -480,14 +783,14 @@
here xx - constant /xx
: put-xx ( adr -- ) xx swap /xx move ;
: get-mbr
- " /ide at 0" open-dev >r
+ " /pci/ide at 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 ( -- )
- ." AX CX BX DX SP BP SI DI" cr
+ ." AX CX DX BX SP BP SI DI" cr
caller-regs >rm-eax 4 + 8 0 do .lreg loop cr
cr
." DS ES FS GS PC FLAGS" cr
More information about the OpenBIOS
mailing list