From b475ea0688868ddfc6bfd41b1b9715430f1d0870 Mon Sep 17 00:00:00 2001 From: Jonas Franz Date: Sat, 20 Jun 2020 14:24:32 +0200 Subject: [PATCH] Add read & write Add PageErrorHandler --- hal/paging.go | 55 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/hal/paging.go b/hal/paging.go index 0743401..b4878b5 100644 --- a/hal/paging.go +++ b/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 }