[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