1
0
mirror of https://github.com/irmen/ksim65.git synced 2024-06-06 22:29:33 +00:00

demo prog and bugfixes in screen and rtc

This commit is contained in:
Irmen de Jong 2019-09-16 02:31:48 +02:00
parent da722cf63a
commit cf543159b4
8 changed files with 167 additions and 39 deletions

View File

@ -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" -> {

View File

@ -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()
}

View File

@ -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

View File

@ -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)

View File

@ -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 ->

View File

@ -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

View 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

Binary file not shown.