Add read & write

Add PageErrorHandler
master
Jonas Franz 4 years ago committed by Jonas Franz
parent f56cfdd5a8
commit b475ea0688
  1. 55
      hal/paging.go

@ -15,6 +15,10 @@ type PageTable map[uint16]*Page
type Address uint16
type PageErrorHandler interface {
handlePageError(address Address, write bool)
}
type MMU struct {
PageTable PageTable
LoadedPages []*Page
@ -22,6 +26,8 @@ type MMU struct {
// pseudo hard drive which holds all pages
drive map[uint16][]float64
pageErrorHandler PageErrorHandler
}
func (address Address) PageNumber() uint16 {
@ -32,7 +38,28 @@ func (address Address) Offset() uint16 {
return uint16(address) & 0x03FF
}
func (mmu *MMU) Find(address Address) {
func NewMMU(pageErrorHandler PageErrorHandler) *MMU {
pageCount := uint16(PageSize / 16)
drive := make(map[uint16][]float64)
pageTable := make(PageTable)
for i := uint16(0); i < pageCount; i++ {
drive[i] = make([]float64, PageSize, PageSize)
pageTable[i] = &Page{
Referenced: false,
RegisterAddress: nil,
PageNumber: i,
}
}
return &MMU{
PageTable: pageTable,
LoadedPages: make([]*Page, 0, 4),
Registers: make([]float64, PageSize*4, PageSize*4),
drive: drive,
pageErrorHandler: pageErrorHandler,
}
}
func (mmu *MMU) Read(address Address) float64 {
// 10 bit for one register in a page
// 6 bit to address the page
// 000010 | 0000000011
@ -44,9 +71,30 @@ func (mmu *MMU) Find(address Address) {
// Page not loaded in "physical" register
if page.RegisterAddress == nil {
// Page Error
// TODO: Logging
mmu.pageErrorHandler(address, false)
mmu.Load(page)
}
page.Referenced = true
return mmu.Registers[page.RegisterOffset()+int(address.Offset())]
}
func (mmu *MMU) Write(address Address, content float64) {
// 10 bit for one register in a page
// 6 bit to address the page
// 000010 | 0000000011
// -> Page 2, offset 3
// Find the page with that number
page := mmu.PageTable[address.PageNumber()]
// Page not loaded in "physical" register
if page.RegisterAddress == nil {
// Page Error
mmu.pageErrorHandler(address, true)
mmu.Load(page)
}
page.Referenced = true
mmu.Registers[page.RegisterOffset()+int(address.Offset())] = content
}
//
@ -54,6 +102,7 @@ func (mmu *MMU) Load(page *Page) {
if len(mmu.LoadedPages) >= 4 {
for index, loadedPage := range mmu.LoadedPages {
if loadedPage.Referenced {
loadedPage.Referenced = false
continue
}
mmu.movePageToDrive(loadedPage)
@ -91,7 +140,7 @@ func (mmu *MMU) movePageToDrive(page *Page) {
for i := 0; i < PageSize-1; i++ {
mmu.drive[page.PageNumber][i] = mmu.Registers[i+page.RegisterOffset()]
}
page.Referenced = false
page.RegisterAddress = nil
}

Loading…
Cancel
Save