|
|
@ -7,7 +7,7 @@ var defaultRegister uint16 = 0 |
|
|
|
type Page struct { |
|
|
|
type Page struct { |
|
|
|
Referenced bool |
|
|
|
Referenced bool |
|
|
|
RegisterAddress *uint16 |
|
|
|
RegisterAddress *uint16 |
|
|
|
Address Address |
|
|
|
PageNumber uint16 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// PageTable uses key as page number
|
|
|
|
// PageTable uses key as page number
|
|
|
@ -16,12 +16,12 @@ type PageTable map[uint16]*Page |
|
|
|
type Address uint16 |
|
|
|
type Address uint16 |
|
|
|
|
|
|
|
|
|
|
|
type MMU struct { |
|
|
|
type MMU struct { |
|
|
|
PageTable *PageTable |
|
|
|
PageTable PageTable |
|
|
|
LoadedPages []*Page |
|
|
|
LoadedPages []*Page |
|
|
|
Registers []float64 // 4k registers
|
|
|
|
Registers []float64 // 4k registers
|
|
|
|
|
|
|
|
|
|
|
|
// pseudo hard drive which holds all pages
|
|
|
|
// pseudo hard drive which holds all pages
|
|
|
|
drive map[Address][]float64 |
|
|
|
drive map[uint16][]float64 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (address Address) PageNumber() uint16 { |
|
|
|
func (address Address) PageNumber() uint16 { |
|
|
@ -32,14 +32,14 @@ func (address Address) Offset() uint16 { |
|
|
|
return uint16(address) & 0x03FF |
|
|
|
return uint16(address) & 0x03FF |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (table PageTable) Find(address Address) { |
|
|
|
func (mmu *MMU) Find(address Address) { |
|
|
|
// 10 bit for one register in a page
|
|
|
|
// 10 bit for one register in a page
|
|
|
|
// 6 bit to address the page
|
|
|
|
// 6 bit to address the page
|
|
|
|
// 000010 | 0000000011
|
|
|
|
// 000010 | 0000000011
|
|
|
|
// -> Page 2, offset 3
|
|
|
|
// -> Page 2, offset 3
|
|
|
|
|
|
|
|
|
|
|
|
// Find the page with that number
|
|
|
|
// Find the page with that number
|
|
|
|
page := table[address.PageNumber()] |
|
|
|
page := mmu.PageTable[address.PageNumber()] |
|
|
|
|
|
|
|
|
|
|
|
// Page not loaded in "physical" register
|
|
|
|
// Page not loaded in "physical" register
|
|
|
|
if page.RegisterAddress == nil { |
|
|
|
if page.RegisterAddress == nil { |
|
|
@ -89,7 +89,7 @@ func (mmu *MMU) findEmptyRegisterAddress() *uint16 { |
|
|
|
func (mmu *MMU) movePageToDrive(page *Page) { |
|
|
|
func (mmu *MMU) movePageToDrive(page *Page) { |
|
|
|
|
|
|
|
|
|
|
|
for i := 0; i < PageSize-1; i++ { |
|
|
|
for i := 0; i < PageSize-1; i++ { |
|
|
|
mmu.drive[page.Address][i] = mmu.Registers[i+page.RegisterOffset()] |
|
|
|
mmu.drive[page.PageNumber][i] = mmu.Registers[i+page.RegisterOffset()] |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
page.RegisterAddress = nil |
|
|
|
page.RegisterAddress = nil |
|
|
@ -97,7 +97,7 @@ func (mmu *MMU) movePageToDrive(page *Page) { |
|
|
|
|
|
|
|
|
|
|
|
func (mmu *MMU) loadPageFromDrive(page *Page) { |
|
|
|
func (mmu *MMU) loadPageFromDrive(page *Page) { |
|
|
|
for i := 0; i < PageSize-1; i++ { |
|
|
|
for i := 0; i < PageSize-1; i++ { |
|
|
|
mmu.Registers[i+page.RegisterOffset()] = mmu.drive[page.Address][i] |
|
|
|
mmu.Registers[i+page.RegisterOffset()] = mmu.drive[page.PageNumber][i] |
|
|
|
} |
|
|
|
} |
|
|
|
page.RegisterAddress = mmu.findEmptyRegisterAddress() |
|
|
|
page.RegisterAddress = mmu.findEmptyRegisterAddress() |
|
|
|
} |
|
|
|
} |
|
|
|