Skip to content

Commit

Permalink
Example for page RW overriding (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
DerelictDrone authored Dec 4, 2023
1 parent 52f9dcc commit 8f72574
Showing 1 changed file with 135 additions and 0 deletions.
135 changes: 135 additions & 0 deletions data/cpuchip/examples/page_rw_override.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
This example assumes you are already familiar with ZASM
as this will be going over advanced features.

This will not go too indepth into how the paging
system works, but instead focus primarily on the feature
to call an interrupt on read or write of a specific page,
to intercept memory requests and handle them internally.

Requires CPU memory model to be 8kb ram/rom or above.

For setup of this example:

1. Connect CPU membus input to a console screen
*/

DATA
interrupt_table:
ALLOC 28*4 // fill interrupt space for 0-27
DB read_mem,0,0,32 // Interrupt 28, called on a delayed memory read
DB write_mem,0,0,32 // Interrupt 29, called on a delayed memory write
ALLOC 1*4

page_table:
ALLOC 16*2 // Entries for the paging table are 2 bytes each.


// For more information on interrupts, read the interrupts example
read_mem:
CLI
CLM // Disable paging features temporarily
CPUGET ESI,63 // The requested address for the request
CPUSET 27,[ESI] // Return the value in LADD
CPUSET 42,4 // Set MEMRQ to 4 to signify read was handled
STM // Reenable paging features after read is performed
CLERR
STI
IRET

write_mem:
CLI
CPUGET EAX,27 // Get value requested for write
CPUGET EDI,63 // Requested address for write
CPUGET EDX,43 // Internal memory size
SUB EDI,128*8 // Subtract page address from it
MUL EDI,2 // Force position to be even(char pos)
MOV ECX,EDI // Diagonal position
MOV EBX,EDI // Horizontal Position
MUL EDI,30 // Convert char pos to be line pos instead
ADD ECX,EDI // Get diagonal position by adding line to char pos

// Print vertical character
MOV [EDX:EDI],EAX
INC EDI // On odd offsets we need to write color
MOV [EDX:EDI],999 // write color to screen
// Print horizontal character
MOV [EDX:EBX],EAX
INC EBX
MOV [EDX:EBX],999
// Print diagonal character
MOV [EDX:ECX],EAX
INC ECX
MOV [EDX:ECX],999

CPUGET EAX,28 // Get LINT to check if we failed any memory I/O
CMP EAX,29 // Check if we're in our own interrupt
JNE shutdown
CPUSET 42,5 // Set MEMRQ to 5 to signify write was handled
CLERR
STI
IRET

shutdown:
STI
CLM
CLEF
INT EAX // repeat error now that we're not in extended mode

CODE
STEF // Set extended flag for interrupt handling
CPUSET 37,page_table // Load page table ptr into PTBL register
CPUSET 38,16 // Set page table entries in PTBE register
LIDTR interrupt_table

MOV EAX,0
// Since only Readable/Writable/Executable are accessible via
// the SPP Instruction, we have to manually create a permissions
// mask for our new pages.

// Using SBIT isn't entirely necessary, to get the number below you can also
// use the constant 232(calculated from 8+32+64+128)
SBIT EAX,3 // (8) Read & Write calls int 28(read) and int 29(write)
SBIT EAX,5 // (32) Readable
SBIT EAX,6 // (64) Writable
SBIT EAX,7 // (128) Executable
ADD EAX,(256*2)
// Runlevel can be obtained from the permission mask with floor(pmask/256)%256
// To set the runlevel, add 256*runlevel to the permission mask
MOV ECX,3 // Set 2 pages
MOV EBX,7*2 // Starting from page 8
ADD EBX,page_table

page_set_loop:
MOV EDI,ECX
MUL EDI,2
MOV [EBX:EDI],EAX // Page byte 0 is the permission mask of the page
INC EDI // Access page byte 1
MOV [EBX:EDI],0 // Page byte 1 is the page this redirects to if the mapped flag is set
LOOP page_set_loop

STM // Set Memory flag to enable memory paging features

/*
Note that, unlike regular console screen prints
this doesn't need to write character to even indexes
and color to odd indexes, since those are both handled
by interrupt 29(write_mem), so we can treat this like
a regular section of memory.
*/

MOV R0,128*8 // Get first index of page 8
MOV ESI,str

print_loop:
MOV [R0],[ESI]
INC R0
INC ESI
CMP [ESI],0
JNE print_loop

CLEF // Disable interrupt handling
INT 2 // End execution.

str:
DB "Hello Wiremod!",0

0 comments on commit 8f72574

Please sign in to comment.