mos6502-workbench 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,28 @@
1
+ ; Demonstrates labels, .byte/.word data, low-byte and high-byte extraction,
2
+ ; and cross-segment absolute addressing.
3
+
4
+ .org $9000
5
+
6
+ message:
7
+ .byte 'O', 'K', 0
8
+
9
+ message_ptr:
10
+ .word message
11
+
12
+ .org $8000
13
+
14
+ start:
15
+ lda #<message
16
+ sta $0200
17
+
18
+ lda #>message
19
+ sta $0201
20
+
21
+ lda message
22
+ sta $0202
23
+
24
+ lda message + 1
25
+ sta $0203
26
+
27
+ done:
28
+ jmp done
@@ -0,0 +1,61 @@
1
+ .org $0000
2
+ current:
3
+ .byte 0
4
+ divisor:
5
+ .byte 0
6
+ prime_count:
7
+ .byte 0
8
+ prime_ptr:
9
+ .word 0
10
+
11
+ .org $8000
12
+ start:
13
+ lda #$00
14
+ sta prime_count
15
+ lda #<$0300
16
+ sta prime_ptr
17
+ lda #>$0300
18
+ sta prime_ptr + 1
19
+ lda #$02
20
+ sta current
21
+
22
+ candidate_loop:
23
+ lda #$02
24
+ sta divisor
25
+
26
+ divisor_loop:
27
+ lda divisor
28
+ cmp current
29
+ beq store_prime
30
+
31
+ lda current
32
+ remainder_loop:
33
+ sec
34
+ sbc divisor
35
+ beq next_candidate
36
+ bcc try_next_divisor
37
+ jmp remainder_loop
38
+
39
+ try_next_divisor:
40
+ inc divisor
41
+ jmp divisor_loop
42
+
43
+ store_prime:
44
+ ldy #$00
45
+ lda current
46
+ sta (prime_ptr), y
47
+ inc prime_ptr
48
+ bne pointer_ready
49
+ inc prime_ptr + 1
50
+ pointer_ready:
51
+ inc prime_count
52
+
53
+ next_candidate:
54
+ inc current
55
+ lda current
56
+ bne candidate_loop
57
+
58
+ done:
59
+ lda prime_count
60
+ sta $02ff
61
+ jmp done
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
4
+ require 'mos6502/workbench'
5
+
6
+ machine = MOS6502::Machine.new
7
+ machine.map_ram(start_address: 0x0000, end_address: 0x7fff)
8
+
9
+ rom = Array.new(0x8000, 0xea)
10
+ rom[0x0000] = 0xa9
11
+ rom[0x0001] = 0x42
12
+ rom[0x0002] = 0x8d
13
+ rom[0x0003] = 0x00
14
+ rom[0x0004] = 0x20
15
+ rom[0x0005] = 0x4c
16
+ rom[0x0006] = 0x05
17
+ rom[0x0007] = 0x80
18
+ rom[0x7ffc] = 0x00
19
+ rom[0x7ffd] = 0x80
20
+
21
+ machine.map_rom(rom, start_address: 0x8000)
22
+ machine.power_on
23
+ machine.run(max_instructions: 3)
24
+
25
+ puts format('PC=%04X cycles=%d mem[2000]=%02X', machine.cpu.program_counter, machine.cpu.cycle_count, machine.cpu.read_byte(0x2000))
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
4
+ require 'mos6502/workbench'
5
+
6
+ #
7
+ # A tiny memory-mapped register used to demonstrate custom devices.
8
+ class ConsoleRegister < MOS6502::Device
9
+ attr_reader :value
10
+
11
+ def initialize
12
+ super
13
+ @value = 0
14
+ end
15
+
16
+ def read_byte(_address)
17
+ value
18
+ end
19
+
20
+ def write_byte(_address, byte)
21
+ @value = byte & 0xff
22
+ end
23
+ end
24
+
25
+ machine = MOS6502::Machine.new(bus: MOS6502::Bus.new)
26
+ machine.map_ram(start_address: 0x0000, end_address: 0x7eff)
27
+ machine.map_device(ConsoleRegister.new, start_address: 0x7f00, end_address: 0x7f00)
28
+
29
+ rom = Array.new(0x8100, 0xea)
30
+ program = [
31
+ 0xa9, 'H'.ord,
32
+ 0x8d, 0x00, 0x7f,
33
+ 0xa9, 'I'.ord,
34
+ 0x8d, 0x00, 0x7f,
35
+ 0x4c, 0x0a, 0x80
36
+ ]
37
+
38
+ program.each_with_index { |byte, offset| rom[offset] = byte }
39
+ rom[0x7ffc] = 0x00
40
+ rom[0x7ffd] = 0x80
41
+
42
+ machine.map_rom(rom, start_address: 0x8000)
43
+
44
+ machine.cpu.subscribe_steps do |event|
45
+ puts format('STEP %04X %-3s %-10s cycles=%d A=%02X', event[:address], event[:mnemonic].to_s.upcase, event[:mode], event[:cycles], event[:snapshot][:accumulator])
46
+ end
47
+
48
+ machine.bus.subscribe_accesses do |event|
49
+ next unless event[:address] == 0x7f00 && event[:operation] == :write
50
+
51
+ puts format("IO write -> '%s'", event[:value].chr)
52
+ end
53
+
54
+ machine.power_on
55
+ machine.run(max_instructions: 5)