public function EINT_15H as boolean : result=true : dim i as integer

//DEBUG.ON 'uncomment to enable debug messages (can be slow for hi-freq events)

'/////////////////////////////// STARTUP //////////////////////////////////////

?? "[INT 15] AX=0x";Hex(cpu.AX,4)

select case true

'*****************************************************************************
'*
'* INT 15H AH=4Fh (BIOS) INTERCEPT KEYBOARD SCANCODE (CALLED BY INT 09H)
'*
'*****************************************************************************

case (cpu.AH=0x4F) : cpu.FLAGS.CF=true 'allow scancode processing
   
'*****************************************************************************
'*
'* INT 15H AH=87h (BIOS) MOVE EXTENDED MEMORY BLOCK (AT+)
'*
'*****************************************************************************

case (cpu.AH=0x87) 
  cpu.AH=0 //success
  dim sz as word=shl(cpu.CX,1) //block size, words
  dim addr=cpu.ESPhisBase/*shl(cpu.ES,4)*/+cpu.SI
  dim src as dword=mem.Word(addr+0x12) or shl(mem.Byte(addr+0x14),16)
  dim dst as dword=mem.Word(addr+0x1A) or shl(mem.Byte(addr+0x1C),16)
  ?? "[INT 15] AH=87h : Move ";sz;" bytes from ";
  ?? Hex(src,8);"h to ";Hex(dst,8);"h"
  mem.Pos=dst : mem.Copy(mem.Object,sz,src)
  cpu.FLAGS.ZF=true : cpu.FLAGS.CF=false
  // dbg.Break

'*****************************************************************************
'*
'* INT 15H AH=88h (BIOS) SIZE OF EXTENDED MEMORY (ABOVE 1Mb, AT+)
'*
'*****************************************************************************

case (cpu.AH=0x88) 
  i=shr(mem.Size,10)-1024 //Kb
  if i<0 then i=0 else if i>0xFFFF then i=0xFFFF //fix if >64Mb
  cpu.AX=i : cpu.FLAGS.CF=false 'success

'*****************************************************************************
'*
'* INT 15H AH=C0h (BIOS) GET SYSTEM CONFIGURATION TABLE
'*
'*****************************************************************************

case (cpu.AH=0xC0)  //TODO
 cpu.BX=0 'hack to avoid segment limit violation (when BX=0xFFFF or similar)
 cpu.AH=0x86 : cpu.FLAGS.CF=true //not supported

'*****************************************************************************
'*
'* INT 15H AX=E801h (BIOS) MEMORY SIZE INFO FOR >64MB CONFIGS (AT+)
'*
'*****************************************************************************

case (cpu.AX=0xE801)

  i=shr(mem.Size,10)-1024 : if i<0 then i=0 //Kb count
  cpu.AX=iif(i<=0x3C00,i,0x3C00) //Kb count between 1M and 16M
  i=(i-0x3C00)/64 : if i<0 then i=0 //64Kb count
  cpu.BX=iif(i<=0xFFFF,i,0xFFFF) //64Kb count above 16Mb
  cpu.CX=cpu.AX : cpu.DX=cpu.BX //whole memory configured
  cpu.FLAGS.CF=false 'success

'//////////////////////////////// FINAL //////////////////////////////////////

//TODO: cpu.AX=0xE820 - get system memory map (modern BIOSes)

case else //not supported
  cpu.AH=0x86 : cpu.FLAGS.CF=true
end select : end function

