|
|
@ -1,7 +1,15 @@ |
|
|
|
package hal |
|
|
|
package hal |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
|
|
|
"fmt" |
|
|
|
|
|
|
|
"math/rand" |
|
|
|
|
|
|
|
"time" |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
const PageSize = 1024 |
|
|
|
const PageSize = 1024 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var seed = rand.NewSource(time.Now().UnixNano()) |
|
|
|
|
|
|
|
|
|
|
|
var defaultRegister uint16 = 0 |
|
|
|
var defaultRegister uint16 = 0 |
|
|
|
|
|
|
|
|
|
|
|
type Page struct { |
|
|
|
type Page struct { |
|
|
@ -100,21 +108,15 @@ func (mmu *MMU) Write(address Address, content float64) { |
|
|
|
//
|
|
|
|
//
|
|
|
|
func (mmu *MMU) Load(page *Page) { |
|
|
|
func (mmu *MMU) Load(page *Page) { |
|
|
|
if len(mmu.LoadedPages) >= 4 { |
|
|
|
if len(mmu.LoadedPages) >= 4 { |
|
|
|
for index, loadedPage := range mmu.LoadedPages { |
|
|
|
|
|
|
|
if loadedPage.Referenced { |
|
|
|
|
|
|
|
loadedPage.Referenced = false |
|
|
|
|
|
|
|
continue |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
mmu.movePageToDrive(loadedPage) |
|
|
|
|
|
|
|
mmu.LoadedPages = append(mmu.LoadedPages[:index], mmu.LoadedPages[index+1:]...) |
|
|
|
|
|
|
|
break |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Everything is referenced, we need to remove one
|
|
|
|
// Everything is referenced, we need to remove one
|
|
|
|
if len(mmu.LoadedPages) == 4 { |
|
|
|
index := rand.New(seed).Intn(4) |
|
|
|
mmu.movePageToDrive(mmu.LoadedPages[3]) |
|
|
|
removedPage := mmu.LoadedPages[index] |
|
|
|
mmu.LoadedPages = mmu.LoadedPages[:3] |
|
|
|
mmu.movePageToDrive(removedPage) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
mmu.loadPageFromDrive(page) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mmu.LoadedPages[index] = page |
|
|
|
|
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
mmu.loadPageFromDrive(page) |
|
|
|
mmu.loadPageFromDrive(page) |
|
|
@ -127,7 +129,7 @@ func (mmu *MMU) findEmptyRegisterAddress() *uint16 { |
|
|
|
for i = 0; i < uint16(len(mmu.module.register)/PageSize); i++ { |
|
|
|
for i = 0; i < uint16(len(mmu.module.register)/PageSize); i++ { |
|
|
|
var isTaken bool |
|
|
|
var isTaken bool |
|
|
|
for _, loadedPage := range mmu.LoadedPages { |
|
|
|
for _, loadedPage := range mmu.LoadedPages { |
|
|
|
if *loadedPage.RegisterAddress == i { |
|
|
|
if loadedPage.RegisterAddress != nil && *loadedPage.RegisterAddress == i { |
|
|
|
isTaken = true |
|
|
|
isTaken = true |
|
|
|
break |
|
|
|
break |
|
|
|
} |
|
|
|
} |
|
|
@ -142,7 +144,9 @@ func (mmu *MMU) findEmptyRegisterAddress() *uint16 { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (mmu *MMU) movePageToDrive(page *Page) { |
|
|
|
func (mmu *MMU) movePageToDrive(page *Page) { |
|
|
|
|
|
|
|
if page.RegisterAddress == nil { |
|
|
|
|
|
|
|
fmt.Printf("PAGE NOT IN MEMORY\n") |
|
|
|
|
|
|
|
} |
|
|
|
for i := 0; i < PageSize-1; i++ { |
|
|
|
for i := 0; i < PageSize-1; i++ { |
|
|
|
mmu.drive[page.PageNumber][i] = mmu.module.register[i+page.RegisterOffset()] |
|
|
|
mmu.drive[page.PageNumber][i] = mmu.module.register[i+page.RegisterOffset()] |
|
|
|
} |
|
|
|
} |
|
|
|