'******************************************************************************
'* 
'* PC/AT 286 (Model 5170) ISA MOTHERBOARD v.1.0 (MOTHERBOARD DEVICE)
'*
'* Supported platform/bus: X86
'*
'* Adapters: CGA
'* 
'* Version history:
'*  - v.1.0 by WadiM (initial emulation)
'*
'****************************************************************************** 

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

//parent PC/AT chipset implementation
public use object CHIPSET_PCAT

//motherboard name
DeviceName="PC/286 Model 5170 Motherboard"
DebugName="PC286_ATMB"

//variables
dim i as integer

//objects
use object FILE_STREAM as file1 
use object FILE_STREAM as file2 

'--------------------------------- Adapters -----------------------------------

//VGA video adapter
public use object VID_VGA as VGA : AddDevice(VGA)
for i=0x3C0 to 0x3CF : pc.WritePort(i)=VGA.PORTS : pc.ReadPort(i)=VGA.PORTS : next
for i=0x3D0 to 0x3DF : pc.WritePort(i)=VGA.PORTS : pc.ReadPort(i)=VGA.PORTS : next
pc.WritePort(0x3B4)=VGA.PORTS : pc.ReadPort(0x3B4)=VGA.PORTS
pc.WritePort(0x3B5)=VGA.PORTS : pc.ReadPort(0x3B5)=VGA.PORTS
pc.WritePort(0x3BA)=VGA.PORTS : pc.ReadPort(0x3BA)=VGA.PORTS
for i=0xA0000/1024 to (0xBFFFF/1024)-1 //VGA video memory
 mem.KBReader(i)=VGA.ReadMemory : mem.KBWriter(i)=VGA.WriteMemory 
next

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

//Handler of non-phisycal memory reading (address bigger than memory size)
function ExternalMemoryReader(Addr as dword, byref Value as byte) as boolean
 if Addr>=0xFC0000 then //BIOS at top of address space
    dim pos as int64=mem.Pos : Value=mem.Byte(Addr-0xF00000)
    mem.pos=pos : result=true
 else : result=false : end if
end

//Device initialization
protected function DEV_INIT(stream as object,byref EventFreq as integer) as boolean
 dim i as integer, j as integer, s as string
 
 'parent call
 if not DEV_INIT(stream,EventFreq) then exit(false)
 if EventFreq<22050 then EventFreq=22050 'to pass POST tests

 'top of address space remapping
 mem.ExternalReader=ExternalMemoryReader

 'load main ROM BIOS files (byte-interleaved pairs)
 s="bin\at111585" : file1.Open(s+".0") : file2.Open(s+".1")
 if file1.Size<>file2.Size then Error("Sizes of paired ROM files must be equal")
 mem.Pos=0x100000-file1.Size*2 : for i=0 to file1.Size-1
 mem.Byte=file1.Byte : mem.Byte=file2.byte : next
 file1.Close : file2.Close

 'load video ROM BIOS files
 //s="bin\trident.bin" : mem.Bytes(0xC0000)=ArrayFile(s) 'VGA BIOS
 s="bin\et4000.bin" : mem.Bytes(0xC0000)=ArrayFile(s) 'VGA BIOS

 'some POST hacks (disable some checks)
 mem.Byte(0xF019E)=0x90 'checksum
 mem.Byte(0xF027F)=0x90 '16-bit dma (step 7)
 mem.Word(0xF0287)=0x9090 '16-bit dma (step 7)
 mem.Byte(0xF05C4)=0x90 'video sync counting
 mem.Byte(0xF13F0)=0x90 : mem.Word=0x9090 'disk controller test

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

 'success 
 result=true
end
