mirror of
https://github.com/irmen/ksim65.git
synced 2025-04-22 11:37:45 +00:00
demo prog and bugfixes in screen and rtc
This commit is contained in:
parent
da722cf63a
commit
cf543159b4
src/main
kotlin/razorvine
resources
@ -175,7 +175,7 @@ class DebugWindow(val vm: VirtualMachine) : JFrame("debugger"), ActionListener {
|
||||
buttonPanel.border = BorderFactory.createTitledBorder("Control")
|
||||
|
||||
val resetBt = JButton("Reset").also { it.actionCommand = "reset" }
|
||||
val cycleBt = JButton("Cycle").also { it.actionCommand = "cycle" }
|
||||
val cycleBt = JButton("Step").also { it.actionCommand = "step" }
|
||||
listOf(resetBt, cycleBt, pauseBt).forEach {
|
||||
it.addActionListener(this)
|
||||
buttonPanel.add(it)
|
||||
@ -192,8 +192,8 @@ class DebugWindow(val vm: VirtualMachine) : JFrame("debugger"), ActionListener {
|
||||
vm.bus.reset()
|
||||
updateCpu(vm.cpu)
|
||||
}
|
||||
e.actionCommand == "cycle" -> {
|
||||
vm.bus.clock()
|
||||
e.actionCommand == "step" -> {
|
||||
vm.stepInstruction()
|
||||
updateCpu(vm.cpu)
|
||||
}
|
||||
e.actionCommand == "pause" -> {
|
||||
|
@ -29,6 +29,7 @@ class VirtualMachine(title: String) {
|
||||
init {
|
||||
ram[Cpu6502.RESET_vector] = 0x00
|
||||
ram[Cpu6502.RESET_vector + 1] = 0x10
|
||||
ram.loadPrg(javaClass.getResource("/vmdemo.prg").toURI())
|
||||
|
||||
bus += rtc
|
||||
bus += timer
|
||||
@ -47,38 +48,26 @@ class VirtualMachine(title: String) {
|
||||
|
||||
var paused = false
|
||||
|
||||
fun clock() {
|
||||
if(!paused) {
|
||||
bus.clock()
|
||||
debugWindow.updateCpu(cpu)
|
||||
fun stepInstruction() {
|
||||
while (cpu.instrCycles > 0) bus.clock()
|
||||
bus.clock()
|
||||
while (cpu.instrCycles > 0) bus.clock()
|
||||
}
|
||||
|
||||
fun start() {
|
||||
val timer = java.util.Timer("clock", true)
|
||||
timer.scheduleAtFixedRate(1, 1) {
|
||||
if(!paused) {
|
||||
repeat(10) {
|
||||
stepInstruction()
|
||||
}
|
||||
debugWindow.updateCpu(cpu)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val machine = VirtualMachine("KSim65 demo virtual machine - using ksim65 v${Version.version}")
|
||||
val v = 0xd000
|
||||
|
||||
machine.bus[v + 0x08] = 20
|
||||
machine.bus[v + 0x09] = 2
|
||||
val text = ">> Hello this is an example text! 1234567890 <<\n" +
|
||||
"next line 1\n" +
|
||||
"next line 2\n" +
|
||||
"next line 3\rnext line 4\rnext line 5\n" +
|
||||
"a mistakk\be\n\n\n\n\n\n\n\n\n\n"
|
||||
text.forEach {
|
||||
machine.bus[v + 0x0a] = it.toShort()
|
||||
}
|
||||
|
||||
repeat(20) {
|
||||
Thread.sleep(100)
|
||||
"time: ${LocalDateTime.now()}\n".forEach { c ->
|
||||
machine.bus[v + 0x0a] = c.toShort()
|
||||
}
|
||||
}
|
||||
|
||||
val timer = java.util.Timer("clock", true)
|
||||
timer.scheduleAtFixedRate(1, 1) {
|
||||
machine.clock()
|
||||
}
|
||||
machine.start()
|
||||
}
|
||||
|
@ -49,8 +49,13 @@ class Bus {
|
||||
*/
|
||||
fun read(address: Address): UByte {
|
||||
memComponents.forEach {
|
||||
if (address >= it.startAddress && address <= it.endAddress)
|
||||
return it[address]
|
||||
if (address >= it.startAddress && address <= it.endAddress) {
|
||||
val data = it[address]
|
||||
require(data in 0..255) {
|
||||
"data must be a byte 0..255"
|
||||
}
|
||||
return data
|
||||
}
|
||||
}
|
||||
return 0xff
|
||||
}
|
||||
@ -60,7 +65,9 @@ class Bus {
|
||||
* Any memory mapped component that listens to the address, will receive the data.
|
||||
*/
|
||||
fun write(address: Address, data: UByte) {
|
||||
require(data in 0..255) { "data must be a byte 0..255" }
|
||||
require(data in 0..255) {
|
||||
"data must be a byte 0..255"
|
||||
}
|
||||
memComponents.forEach {
|
||||
if (address >= it.startAddress && address <= it.endAddress)
|
||||
it[address] = data
|
||||
|
@ -1,5 +1,6 @@
|
||||
package razorvine.ksim65.components
|
||||
|
||||
import razorvine.examplemachine.ScreenDefs
|
||||
import razorvine.ksim65.IHostInterface
|
||||
import kotlin.math.min
|
||||
|
||||
@ -67,11 +68,17 @@ class Display(
|
||||
|
||||
override operator fun get(address: Address): UByte {
|
||||
return when(address-startAddress) {
|
||||
0x00 -> charposX.toShort()
|
||||
0x01 -> charposY.toShort()
|
||||
0x02 -> {
|
||||
if(charposY in 0 until charHeight && charposX in 0 until charWidth) {
|
||||
charMatrix[charposY][charposX]
|
||||
} else 0xff
|
||||
}
|
||||
0x03 -> (pixelX and 0xff).toShort()
|
||||
0x04 -> (pixelX ushr 8).toShort()
|
||||
0x05 -> (pixelY and 0xff).toShort()
|
||||
0x06 -> (pixelY ushr 8).toShort()
|
||||
0x07 -> if(host.getPixel(pixelX, pixelY)) 1 else 0
|
||||
0x08 -> cursorX.toShort()
|
||||
0x09 -> cursorY.toShort()
|
||||
@ -99,8 +106,10 @@ class Display(
|
||||
0x05 -> pixelY = (pixelY and 0xff00) or data.toInt()
|
||||
0x06 -> pixelY = (pixelY and 0x00ff) or (data.toInt() shl 8)
|
||||
0x07 -> {
|
||||
if(data==0.toShort()) host.clearPixel(pixelX, pixelY)
|
||||
else host.setPixel(pixelX, pixelY)
|
||||
if(pixelX in 0 until ScreenDefs.SCREEN_WIDTH && pixelY in 0 until ScreenDefs.SCREEN_HEIGHT) {
|
||||
if (data == 0.toShort()) host.clearPixel(pixelX, pixelY)
|
||||
else host.setPixel(pixelX, pixelY)
|
||||
}
|
||||
}
|
||||
0x08 -> cursorX = min(data.toInt() and 65535, charWidth-1)
|
||||
0x09 -> cursorY = min(data.toInt() and 65535, charHeight-1)
|
||||
|
@ -1,7 +1,9 @@
|
||||
package razorvine.ksim65.components
|
||||
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import java.net.URL
|
||||
import java.nio.file.Paths
|
||||
|
||||
/**
|
||||
* A RAM chip with read/write memory.
|
||||
@ -31,7 +33,14 @@ class Ram(startAddress: Address, endAddress: Address) : MemoryComponent(startAdd
|
||||
* Load a c64-style prg program. This file type has the load address as the first two bytes.
|
||||
*/
|
||||
fun loadPrg(filename: String) {
|
||||
val bytes = File(filename).readBytes()
|
||||
loadPrg(Paths.get(filename).toUri())
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a c64-style prg program. This file type has the load address as the first two bytes.
|
||||
*/
|
||||
fun loadPrg(file: URI) {
|
||||
val bytes = File(file).readBytes()
|
||||
val loadAddress = (bytes[0].toInt() or (bytes[1].toInt() shl 8)) and 65535
|
||||
val baseAddress = loadAddress - startAddress
|
||||
bytes.drop(2).forEachIndexed { index, byte ->
|
||||
|
@ -50,11 +50,11 @@ class RealTimeClock(startAddress: Address, endAddress: Address) : MemMappedCompo
|
||||
0x05 -> LocalTime.now().minute.toShort()
|
||||
0x06 -> LocalTime.now().second.toShort()
|
||||
0x07 -> {
|
||||
val ms = LocalTime.now().nano / 1000
|
||||
val ms = LocalTime.now().nano / 1000000
|
||||
(ms and 255).toShort()
|
||||
}
|
||||
0x08 -> {
|
||||
val ms = LocalTime.now().nano / 1000
|
||||
val ms = LocalTime.now().nano / 1000000
|
||||
(ms ushr 8).toShort()
|
||||
}
|
||||
else -> 0xff
|
||||
|
114
src/main/resources/vmdemo.asm
Normal file
114
src/main/resources/vmdemo.asm
Normal file
@ -0,0 +1,114 @@
|
||||
|
||||
.cpu "6502"
|
||||
|
||||
DISPLAY = $d000
|
||||
RTC = $d100
|
||||
TIMER = $d200
|
||||
MOUSE = $d300
|
||||
KEYBOARD = $d400
|
||||
SCREEN_WIDTH=640
|
||||
|
||||
* = $1000
|
||||
|
||||
start
|
||||
sei
|
||||
ldx #$ff
|
||||
txs
|
||||
cli
|
||||
|
||||
; ------- fill the screen
|
||||
ldx #0
|
||||
ldy #0
|
||||
fillscreen
|
||||
stx DISPLAY+0
|
||||
sty DISPLAY+1
|
||||
lda character
|
||||
sta DISPLAY+2 ; plot the char on the screen
|
||||
inc character
|
||||
inx
|
||||
cpx #80
|
||||
bne fillscreen
|
||||
ldx #0
|
||||
iny
|
||||
cpy #30
|
||||
bne fillscreen
|
||||
|
||||
; ------- clear the screen
|
||||
lda #$0c ; form feed (clear screen)
|
||||
sta DISPLAY+$0a
|
||||
|
||||
; ------- draw pixel line
|
||||
pixelline
|
||||
ldx pix_x
|
||||
stx DISPLAY+3
|
||||
ldx pix_x+1
|
||||
stx DISPLAY+4
|
||||
ldx pix_y
|
||||
stx DISPLAY+5
|
||||
ldx pix_y+1
|
||||
stx DISPLAY+6
|
||||
lda #1
|
||||
sta DISPLAY+7 ; plot
|
||||
lda pix_x
|
||||
clc
|
||||
adc #2
|
||||
sta pix_x
|
||||
bcc +
|
||||
inc pix_x+1
|
||||
+ inc pix_y
|
||||
bne +
|
||||
inc pix_y+1
|
||||
+ lda pix_x+1
|
||||
cmp #>SCREEN_WIDTH
|
||||
bcc pixelline
|
||||
bne stop1
|
||||
lda pix_x
|
||||
cmp #<SCREEN_WIDTH
|
||||
bcc pixelline
|
||||
bcs stop1
|
||||
pix_x .word 0
|
||||
pix_y .word 0
|
||||
|
||||
stop1
|
||||
|
||||
;--------- draw with mouse
|
||||
mousedraw
|
||||
ldx MOUSE+0
|
||||
ldy MOUSE+2
|
||||
stx DISPLAY+3
|
||||
sty DISPLAY+5
|
||||
ldx MOUSE+1
|
||||
ldy MOUSE+3
|
||||
stx DISPLAY+4
|
||||
sty DISPLAY+6
|
||||
lda #1
|
||||
sta DISPLAY+7 ; plot pixel
|
||||
jmp mousedraw
|
||||
|
||||
|
||||
;--------- RTC display TODO
|
||||
ldy #0
|
||||
lda #0
|
||||
sta DISPLAY+0
|
||||
sta DISPLAY+1
|
||||
rtcloop
|
||||
ldx #0
|
||||
readrtc
|
||||
lda RTC,x
|
||||
sta DISPLAY+2
|
||||
inc DISPLAY+0
|
||||
inx
|
||||
cpx #9
|
||||
bne readrtc
|
||||
lda #0
|
||||
sta DISPLAY+0
|
||||
iny
|
||||
sty DISPLAY+1
|
||||
cpy #20
|
||||
bne rtcloop
|
||||
|
||||
|
||||
done jmp done
|
||||
|
||||
|
||||
character .byte 0
|
BIN
src/main/resources/vmdemo.prg
Normal file
BIN
src/main/resources/vmdemo.prg
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user