Add MemoryView component for memory rendering, refactor BufferedImage for RGB manipulation, and cleanup unused methods and comments in several classes.

This commit is contained in:
2025-08-14 21:03:03 +02:00
parent 9f295b2fb9
commit d5314ce046
11 changed files with 331 additions and 42 deletions

View File

@@ -1,28 +1,26 @@
package mtmc.emulator
class BufferedImage(width: Int, height: Int, type: Int) {
fun getWidth(): Int {
TODO("Not yet implemented")
}
fun getHeight(): Int {
TODO("Not yet implemented")
}
class BufferedImage(
val width: Int,
val height: Int,
val type: Int
) {
val display = ByteArray(width * height * 4)
fun getRGB(x: Int, y: Int): Int {
TODO("Not yet implemented")
}
fun getType(): Int {
TODO("Not yet implemented")
return display[x * 4 + y * width * 4 + 0].toInt() +
display[x * 4 + y * width * 4 + 1].toInt() shl 8 +
display[x * 4 + y * width * 4 + 2].toInt() shl 16
}
fun setRGB(x: Int, y: Int, intVal: Int) {
TODO("Not yet implemented")
display[x * 4 + y * width * 4 + 0] = intVal.toByte()
display[x * 4 + y * width * 4 + 1] = (intVal shr 8).toByte()
display[x * 4 + y * width * 4 + 2] = (intVal shr 16).toByte()
}
}
class Dimension(
val width: Int,
val height: Int
)
)

File diff suppressed because one or more lines are too long

View File

@@ -67,7 +67,6 @@ class MonTanaMiniComputer {
// reset memory
initMemory()
val codeBoundary = code.size
code.copyInto(memory, 0, 0, codeBoundary)
setRegisterValue(Register.CB, codeBoundary - 1)
@@ -843,7 +842,7 @@ class MonTanaMiniComputer {
breakpoints[address] = (if (active) 1.toByte() else 0.toByte())
}
private fun start() {
fun start() {
console.start() // start the interactive console
}
@@ -1011,16 +1010,8 @@ class MonTanaMiniComputer {
return true
}
val isMcp = getBits(16, 8, instruction) == 5.toShort()
if (isMcp) {
return true
}
return false
}
fun main(args: Array<String>) {
val computer = MonTanaMiniComputer()
computer.speed = 1 // default to 1hz
computer.start()
return isMcp
}
}
}

View File

@@ -2,17 +2,28 @@ package mtmc
import kotlinx.browser.document
import kotlinx.html.div
import kotlinx.html.style
import mtmc.emulator.MonTanaMiniComputer
import mtmc.view.MTMCView
import nl.astraeus.komp.HtmlBuilder
import nl.astraeus.komp.Komponent
class HelloKomponent : Komponent() {
override fun HtmlBuilder.render() {
div {
style = "color: red;"
+ "Hello, world!"
}
}
}
fun main() {
Komponent.create(document.body!!, HelloKomponent())
val computer = MonTanaMiniComputer()
computer.speed = 1 // default to 1hz
val view = MTMCView(computer)
Komponent.create(document.body!!, view)
computer.start()
}

View File

@@ -0,0 +1,19 @@
package mtmc.view
import kotlinx.html.div
import mtmc.emulator.MonTanaMiniComputer
import nl.astraeus.komp.HtmlBuilder
import nl.astraeus.komp.Komponent
class ControlView(
val computer: MonTanaMiniComputer
) : Komponent() {
override fun HtmlBuilder.render() {
div {
+"Controls view"
}
}
}

View File

@@ -0,0 +1,36 @@
package mtmc.view
import kotlinx.html.div
import mtmc.emulator.MonTanaMiniComputer
import nl.astraeus.komp.HtmlBuilder
import nl.astraeus.komp.Komponent
class MTMCView(
val computer: MonTanaMiniComputer
) : Komponent() {
val controlView = ControlView(computer)
val registerView = RegisterView(computer)
val memoryView = MemoryView(computer)
override fun HtmlBuilder.render() {
div("container") {
div("left-column") {
include(controlView)
include(registerView)
include(memoryView)
}
div("middle-column") {
div {
+"Console"
}
div {
+"Shell"
}
}
div("right-column") {
+"Files"
}
}
}
}

View File

@@ -0,0 +1,40 @@
package mtmc.view
import kotlinx.html.div
import kotlinx.html.table
import kotlinx.html.td
import kotlinx.html.tr
import mtmc.emulator.MonTanaMiniComputer
import nl.astraeus.komp.HtmlBuilder
import nl.astraeus.komp.Komponent
fun ByteArray.asHex(address: Int): String {
val value = this[address].toInt() + this[address + 1].toInt() * 256
return value.toShort().toHexString()
}
class MemoryView(
val computer: MonTanaMiniComputer
) : Komponent() {
override fun HtmlBuilder.render() {
div("memory-panel") {
div("memory-header") {
+"Memory"
}
div("memory") {
table {
for (address in 0..<computer.memory.size step 16) {
tr {
for (offset in 0..<8) {
td {
+computer.memory.asHex(address + offset)
}
}
}
}
}
}
}
}
}

View File

@@ -0,0 +1,70 @@
package mtmc.view
import kotlinx.html.TABLE
import kotlinx.html.classes
import kotlinx.html.div
import kotlinx.html.hr
import kotlinx.html.table
import kotlinx.html.td
import kotlinx.html.tr
import mtmc.emulator.MonTanaMiniComputer
import mtmc.emulator.Register
import nl.astraeus.komp.HtmlBuilder
import nl.astraeus.komp.Komponent
class RegisterView(
val computer: MonTanaMiniComputer
) : Komponent() {
override fun HtmlBuilder.render() {
div {
+"Register view"
table("register-table") {
for (index in 0..<16) {
showRegister(index)
}
tr {
td {
colSpan = "3"
hr {}
}
}
showRegister(16)
showRegister(17)
tr {
td {
colSpan = "3"
+"Flags"
}
}
}
}
}
private fun TABLE.showRegister(register: Int) {
val name = Register.fromInteger(register)
val value = computer.registerFile[register]
tr {
td {
+name
}
td("register-lights") {
for (bit in 15 downTo 0) {
div("blinken") {
if (value.toInt() and (1 shl bit) == 0) {
classes += "off"
}
if (bit % 4 == 0) {
classes += "space"
}
}
}
}
td("align-right") {
+"$value"
}
}
}
}

View File

@@ -0,0 +1,124 @@
html, body {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
overscroll-behavior: none;
}
.container {
display: grid;
grid-template-columns: 450px 450px 1fr;
grid-template-rows: 1fr;
overflow-y: auto;
gap: 5px;
background-color: #ccc;
}
.left-column {
grid-template-rows: auto auto minmax(0, 1fr);
display: grid;
grid-gap: 4px;
height: 100dvh;
max-height: 100dvh;
min-width: 450px;
max-width: 450px;
}
.middle-column {
background-color: #eee;
grid-template-rows: auto minmax(0, 1fr);
display: grid;
grid-gap: 4px;
height: 100dvh;
max-height: 100dvh;
min-width: 450px;
max-width: 450px;
}
.right-column {
background-color: #eee;
grid-template-rows: auto;
display: grid;
grid-gap: 4px;
height: 100dvh;
max-height: 100dvh;
min-width: 450px;
}
.align-right {
text-align: right;
}
/* registers */
table.register-table {
font-family: monospace;
width: 100%;
padding: 5px;
background-color: black;
color: white;
border-radius: 8px;
}
table.register-table tr td .align-right {
text-align: right;
}
table.register-table tr td.register-lights {
padding-left: 20px;
}
.blinken {
display: inline-block;
margin-right: 2px;
height: 6px;
width: 6px;
border-radius: 6px;
padding: 3px;
background-color: red;
}
.blinken.off {
background-color: #5c0119;
}
.blinken.space {
margin-right: 8px;
}
/* memory */
.memory-panel {
background-color: #eee;
display: flex;
flex-direction: column;
}
.memory-header {
font-family: monospace;
font-weight: bold;
font-size: 16px;
/* overflow: auto; */
padding: 4px;
}
.memory {
font-family: monospace;
overflow: auto;
}
/* console */
.small-button {
transform: rotate(-25deg) translateY(20px) translateX(-20px);
margin: 2px;
width: 50px;
background-color: #7e777b;
border: 1px solid dimgray;
border-radius: 8px;
color: whitesmoke;
box-shadow: rgb(0, 0, 0, .2) 2px 2px 1px 1px;
}

View File

@@ -7,9 +7,9 @@ import io.undertow.predicate.Predicates
import io.undertow.server.handlers.encoding.ContentEncodingRepository
import io.undertow.server.handlers.encoding.EncodingHandler
import io.undertow.server.handlers.encoding.GzipEncodingProvider
import nl.astraeus.logger.Logger
import mtmc.db.Database
import mtmc.web.RequestHandler
import nl.astraeus.logger.Logger
val log = Logger()
@@ -58,7 +58,6 @@ fun main() {
.setServerOption(UndertowOptions.SHUTDOWN_TIMEOUT, 1000)
.build()
println("Starting undertow server at port 6007...")
println("Starting undertow server at port $SERVER_PORT...")
server?.start()
}

View File

@@ -3,6 +3,7 @@ package mtmc.web
import kotlinx.html.body
import kotlinx.html.head
import kotlinx.html.html
import kotlinx.html.link
import kotlinx.html.meta
import kotlinx.html.script
import kotlinx.html.stream.appendHTML
@@ -18,7 +19,7 @@ fun generateIndex(patch: String?): String {
result.appendHTML(true).html {
head {
title(pageTitle)
//link("/css/all.min.css", "stylesheet")
link("/mtmc.css", "stylesheet")
}
body {
script(src = "/$repoName.js") {}