duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit a680f1ecf8953f05f92d55ff0b508fb79dd03c5b
parent ee0beaf1bbed9779c107ea59d4ca605400dd4e56
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Thu, 21 Jul 2022 19:51:42 -0400

asm/i386: improve modrm handling in 16bit mode

Also add LGDT and LIDT.

Diffstat:
Mfs/asm/i386.fs | 23+++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/fs/asm/i386.fs b/fs/asm/i386.fs @@ -7,7 +7,6 @@ 4 const SP 5 const BP 6 const SI 7 const DI 0 const AL 1 const CL 2 const DL 3 const BL 4 const AH 5 const CH 6 const DH 7 const BH -5 const MEM \ mod 0 + r/m 5 == abs memory 4 const SIB \ mod 0/1/2 + r/m 4 == SIB 0 value op8b \ is current op in 8bit mode? @@ -23,11 +22,13 @@ \ Utilities : asm$ 0 to op8b 1 to opdirec 3 to opmod -1 to opreg -1 to oprm 0 to imm? ; -: _err abort" argument error" ; +: _err asm$ abort" argument error" ; : _assert not if _err then ; : w, here w! 2 allot ; : isbyte? ( n -- f ) $100 < ; : is16bit? realmode ; +\ in 16bit, abs mem = mod0 + rm 6, in 32-bit, it's rm 5 +: memoprm 5 is16bit? + ; : dw, is16bit? if w, else , then ; : dwc, op8b if c, else dw, then ; @@ -57,7 +58,7 @@ : disp, ( -- ) \ write down displacement if needed. opmod case - 0 of = oprm MEM = if disp dw, then endof + 0 of = oprm memoprm = if disp dw, then endof 1 of = disp c, endof 2 of = disp dw, endof endcase ; @@ -107,15 +108,24 @@ AL _ al BL _ bl CL _ cl DL _ dl AH _ ah BH _ bh CH _ ch DH _ dh : i) ( imm -- ) 1 to imm? to imm ; +: 16breg>[oprm] ( reg ) case + SI of = 4 endof + DI of = 5 endof + BP of = 6 endof + BX of = 7 endof + _err + endcase ; + : d) ( disp -- ) to disp oprm 0< if \ first argument. we need to move it to oprm and change direction opreg to oprm -1 to opreg 0 to opdirec then + is16bit? if oprm 16breg>[oprm] to oprm then oprm SP = if $24 to sib then \ special case for ESP disp case - of not oprm MEM = to opmod endof \ mod = 0 except if rm==MEM + of not oprm memoprm = to opmod endof \ mod = 0 except if rm==MEM of isbyte? 1 to opmod endof 2 to opmod endcase ; @@ -124,7 +134,7 @@ AL _ al BL _ bl CL _ cl DL _ dl AH _ ah BH _ bh CH _ ch DH _ dh oprm 0< _assert \ can't have m) with second argument opreg 0< if \ first argument, we invert direction 0 to opdirec then - 0 to opmod MEM to oprm ; + 0 to opmod memoprm to oprm ; \ Operations @@ -161,7 +171,7 @@ $840f op jz, $850f op jnz, $04e9 op jmp, $02e8 op call, \ Single operand -\ opcode format 00000000 00000rrr mmmmmmmm mmmmmm00 +\ opcode format 00000000 00000rrr mmmmmmmm mmmmmmmm \ r = opreg override \ m = modrm opcode : op ( reg opcode -- ) doer , does> @ ( opcode -- ) @@ -169,6 +179,7 @@ $04e9 op jmp, $02e8 op call, $0400f7 op mul, $0300f7 op neg, $0200f7 op not, $0100ff op dec, $0000ff op inc, $009f0f op setg, $009c0f op setl, $00940f op setz, $00950f op setnz, +$02010f op lgdt, $03010f op lidt, \ Two operands \ opcode format 00000000 ssssssss iiiiirrr mmmmmm00