'******************************************************************************
'* 
'* PC/XT "ES-1841" (SOVIET) MOTHERBOARD v.1.0 (MOTHERBOARD DEVICE)
'*
'* Supported platform/bus: X86
'* 
'* Version history:
'*  - v.1.0 by WadiM (initial emulation)
'*
'****************************************************************************** 

//parent PC/XT chipset implementation
public use object CHIPSET_PCXT

//motherboard name
DeviceName="ES-1841 Motherboard"
DebugName="ES1841_MB"

//variables
dim i as integer

'---------------------------- Video adapter (CGA) -----------------------------

//CGA video adapter (ES modification)
public use object VID_CGA as CGA : AddISADevice(CGA,-1,-1)
pc.WritePort(0x3D4)=CGA.CRT_INDEX_PORT : pc.ReadPort(0x3D4)=CGA.CRT_INDEX_PORT
pc.WritePort(0x3D5)=CGA.CRT_DATA_PORT  : pc.ReadPort(0x3D5)=CGA.CRT_DATA_PORT
pc.WritePort(0x3D8)=CGA.MODE_PORT      : pc.ReadPort(0x3D8)=CGA.MODE_PORT
pc.WritePort(0x3D9)=CGA.COLOR_PORT     : pc.ReadPort(0x3D9)=CGA.COLOR_PORT
pc.WritePort(0x3DB)=CGA.PEN_RESET_PORT : pc.WritePort(0x3DC)=CGA.PEN_SET_PORT
pc.ReadPort(0x3DA)=CGA.STATE_PORT

//Bit 0 of port 3DFh used to switch between video buffer and chargen access
dim P3DF as byte=0 'videobuffer by default
property PORT_3DF(Value as byte) 
 if (P3DF and 1)<>(Value and 1) then 'switching
   if (Value and 1)<>0 then 'chargen
     for i=0xB8000/1024 to (0xBFFFF/1024)-1 
       mem.KBReader(i)=CGA.Chargen.ReadMemory 
       mem.KBWriter(i)=CGA.Chargen.WriteMemory 
     next
   else 'videobuffer 
     for i=0xB8000/1024 to (0xBFFFF/1024)-1 
       mem.KBReader(i)=CGA.ReadMemory : mem.KBWriter(i)=CGA.WriteMemory 
     next
   end if
 end
 P3DF=Value
end

function PORT_3DF as byte : result=P3DF : end
pc.WritePort(0x3DF)=PORT_3DF : pc.ReadPort(0x3DF)=PORT_3DF

'---------------------------- DEVICE Interface --------------------------------

//Device initialization
protected function DEV_INIT(stream as object,byref EventFreq as integer) as boolean

 'parent call
 if not DEV_INIT(stream,EventFreq) then exit(false)
 if EventFreq<22050 then EventFreq=22050 'to pass POST tests

 'load ROM BIOS files (byte-interleaved pairs)
 dim i as integer, j as integer, a(0 to 2047) as byte, b(0 to 2047) as byte

 'BIOS part 1/4
 a=ArrayFile("BIN\18410112.BIN") 
 b=ArrayFile("BIN\18410113.BIN") 
 j=0x100000-0x4000 : for i=LBound(a) to UBound(a) 
 mem.Byte(j)=a(i) : j=j+1 : mem.Byte(j)=b(i) : j=j+1 : next

 'BIOS part 2/4
 a=ArrayFile("BIN\18410114.BIN") 
 b=ArrayFile("BIN\18410115.BIN") 
 j=0x100000-0x3000 : for i=LBound(a) to UBound(a) 
 mem.Byte(j)=a(i) : j=j+1 : mem.Byte(j)=b(i) : j=j+1 : next

 'BIOS part 3/4
 a=ArrayFile("BIN\18410116.BIN") 
 b=ArrayFile("BIN\18410117.BIN") 
 j=0x100000-0x2000 : for i=LBound(a) to UBound(a) 
 mem.Byte(j)=a(i) : j=j+1 : mem.Byte(j)=b(i) : j=j+1 : next

 'BIOS part 4/4
 a=ArrayFile("BIN\18410118.BIN") 
 b=ArrayFile("BIN\18410119.BIN") 
 j=0x100000-0x1000 : for i=LBound(a) to UBound(a) 
 mem.Byte(j)=a(i) : j=j+1 : mem.Byte(j)=b(i) : j=j+1 : next

 'some POST hacks (disable some checks)
 mem.Bytes(0xFE159)=Array(0x90,0x90,0x90) 'no memory boards configuration check
 mem.Word(0x413)=640 '640Kb of memory (emulated result of previous operation)

 'mark BIOS area as read-only 
 for i=0xA0000/1024 to 0xFFFFF/1024 : mem.KBAccess(i)=memReadOnly : next
 'mark CGA memory as read-write 
 for i=0xB8000/1024 to 0xBFFFF/1024 : mem.KBAccess(i)=memReadWrite : next

 'success
 result=true

end


