Mercurial > repos > blastem
changeset 2716:033d8d4308e3
Fix enough issues in uPD78K/II core so that LaserActive firmware regularly polls front-panel button state
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 12 Jul 2025 22:25:20 -0700 |
parents | 8d4ee0c04ee0 |
children | 04007ac9ee3b |
files | cpu_dsl.py upd78k2.cpu upd78k2_util.c upd78k2run.c |
diffstat | 4 files changed, 156 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/cpu_dsl.py Fri Jul 11 10:55:33 2025 -0700 +++ b/cpu_dsl.py Sat Jul 12 22:25:20 2025 -0700 @@ -2462,6 +2462,8 @@ info = {} line_num = 0 cur_object = None + usedInstNames = set() + usedBitPatterns = set() for line in f: line_num += 1 line,_,comment = line.partition('#') @@ -2530,7 +2532,15 @@ else: fields[char] = (curbit, 1) curbit -= 1 - cur_object = Instruction(value, fields, name.strip()) + name = name.strip() + if name in usedInstNames: + raise Exception(f'Instruction name {name} was already used!') + usedInstNames.add(name) + pattern = (table, bitpattern) + if pattern in usedBitPatterns: + raise Exception(f'Pattern {pattern} was already defined') + usedBitPatterns.add(pattern) + cur_object = Instruction(value, fields, name) instructions.setdefault(table, []).append(cur_object) elif line.strip() == 'regs': if registers is None:
--- a/upd78k2.cpu Fri Jul 11 10:55:33 2025 -0700 +++ b/upd78k2.cpu Sat Jul 12 22:25:20 2025 -0700 @@ -9,7 +9,7 @@ body upd78k2_run_op sync_cycle upd78k2_sync_cycle interrupt upd78k2_interrupt - extra_tables sfr bit1 bit2 muldiv base sfrbit spmov indexed regind alt_base alt_indexed alt_regind mov_reg xch_reg + extra_tables sfr bit1 bit2 muldiv base sfrbit spmov indexed regind alt_base alt_indexed alt_regind mov_reg xch_reg shr shl include upd78k2_util.c regs main 8 x a c b e d l h @@ -28,6 +28,7 @@ mem_pointers ptr8 4 port_data 8 8 port_mode 8 8 + port_input 8 8 puo 8 #pull-up option register pmc3 8 #port 3 pin configuration cr00 16 #16-bit timer comapre register 0 @@ -51,6 +52,8 @@ intm0 8 #External interrupt mode register 0 intm1 8 #External interrupt mode register 1 ist 8 #Interrupt status register + io_read ptrupd_io_fun + io_write ptrupd_io_fun iram 8 256 flags register psw @@ -67,6 +70,7 @@ void init_upd78k2_opts(upd78k2_options *opts, memmap_chunk const *chunks, uint32_t num_chunks); upd78k2_context *init_upd78k2_context(upd78k2_options *opts); void upd78k2_sync_cycle(upd78k2_context *upd, uint32_t target_cycle); + typedef void (upd_io_fun)(upd78k2_context *upd, uint8_t offset); #Prefix bytes # 0000 0001 -> saddr becomes sfr, mem becomes &mem @@ -77,6 +81,8 @@ # 0000 1001 -> mov !addr16/stbc # 0000 1010 -> indexed mode # 0001 0110 -> register indirect +# 0011 0000 -> shift/rotate right +# 0011 0001 -> shift/rotate left sfr_read arg offset 8 @@ -350,6 +356,14 @@ upd78k2_op_fetch dispatch scratch1 xch_reg +00110000 shr_prefix + upd78k2_op_fetch + dispatch scratch1 shr + +00110001 shl_prefix + upd78k2_op_fetch + dispatch scratch1 shl + sfr 00000110 alt_base_prefix upd78k2_op_fetch dispatch scratch1 alt_base @@ -370,13 +384,13 @@ dst += src update_flags ZAC case 1 - adc dst src dst + adc src dst dst update_flags ZAC case 2 dst -= src update_flags ZAC case 3 - sbc dst src dst + sbc src dst dst update_flags ZAC case 4 dst &= src @@ -388,7 +402,7 @@ dst |= src update_flags Z case 7 - cmp dst src + cmp src dst update_flags ZAC end @@ -484,7 +498,28 @@ saddr_read offset meta dst scratch1 aluop P immed - saddr_write offset scratch1 + if P != 7 + saddr_write offset scratch1 + end + +10011PPP alu_a_saddr + upd78k2_op_fetch + saddr_read scratch1 + meta dst a + aluop P scratch1 + +01111PPP alu_saddr_saddr + local dst_offset 8 + local dst_tmp 8 + upd78k2_op_fetch + dst_offset = scratch1 + saddr_read dst_offset + dst_tmp = scratch1 + upd78k2_op_fetch + saddr_read scratch1 + meta dst dst_tmp + aluop P scratch1 + saddr_write dst_offset dst_tmp 001011PP alu_ax_immed invalid P 0 @@ -840,7 +875,7 @@ scratch2 = scratch1 sfr_write scratch2 a -00011100 mov_ax_saddr +00011100 movw_ax_saddr local offset 8 upd78k2_op_fetch offset = scratch1 @@ -850,7 +885,7 @@ saddr_read offset a = scratch1 -00011010 mov_saddr_ax +00011010 movw_saddr_ax local offset 8 upd78k2_op_fetch offset = scratch1 @@ -858,7 +893,7 @@ offset += 1 saddr_write offset a -00010001 mov_ax_saddr +00010001 movw_ax_sfr local offset 8 upd78k2_op_fetch offset = scratch1 @@ -868,7 +903,7 @@ sfr_read offset a = scratch1 -00010011 mov_saddr_ax +00010011 movw_sfr_ax local offset 8 upd78k2_op_fetch offset = scratch1 @@ -906,7 +941,7 @@ upd78k2_op_fetch offset = scratch1 saddr_read offset - sub scratch1 1 scratch1 0 + sub 1 scratch1 scratch1 0 update_flags ZA saddr_write offset scratch1 @@ -944,6 +979,16 @@ pc += scratch1 end +0011001R dbnz_r + local reg 8 + reg = R + 2 + upd78k2_op_fetch + main.reg -= 1 + if != + sext 16 scratch1 scratch1 + pc += scratch1 + end + bit1 10100BBB bf_psw local mask 8 upd78k2_op_fetch @@ -1071,12 +1116,12 @@ local offset 8 offset = T << 1 offset += 0x40 - mem_read_no_exp T + mem_read_no_exp offset address = scratch1 - scratch1 = T + 1 - mem_read_no_exp scratch1 + offset += 1 + mem_read_no_exp offset scratch1 <<= 8 - address |= 8 + address |= scratch1 push_word pc pc = address @@ -1229,6 +1274,7 @@ upd78k2_op_fetch if offset = 0xFE psw = scratch1 + update_sync else sfr_write offset scratch1 end @@ -1415,7 +1461,7 @@ scratch1 &= mask sfr_write offset scratch1 -10110BBB set1_saddr_cy +10110BBB set1_saddr local mask 8 local offset 8 upd78k2_op_fetch @@ -1425,7 +1471,7 @@ scratch1 |= mask saddr_write offset scratch1 -10100BBB clr1_saddr_cy +10100BBB clr1_saddr local mask 8 local offset 8 upd78k2_op_fetch @@ -1443,6 +1489,56 @@ psw = scratch1 update_sync +shr 10NNNRRR shr_r + local cyc 32 + main.R >>= N + update_flags ZA0C + cyc = 4 * N + cyc += 2 + cycles cyc + +shl 10NNNRRR shl_r + local cyc 32 + main.R <<= N + update_flags ZA0C + cyc = 4 * N + cyc += 2 + cycles cyc + +shr 11NNNRRR shrw_rp + local cyc 32 + local reg 8 + local tmp 16 + reg = R + 1 + tmp = main.reg << 8 + reg -= 1 + tmp |= main.reg + tmp >>= N + update_flags ZA0C + main.reg = tmp + reg += 1 + main.reg = tmp >> 8 + cyc = 6 * N + cyc += 2 + cycles cyc + +shl 11NNNRRR shlw_rp + local cyc 32 + local reg 8 + local tmp 16 + reg = R + 1 + tmp = main.reg << 8 + reg -= 1 + tmp |= main.reg + tmp <<= N + update_flags ZA0C + main.reg = tmp + reg += 1 + main.reg = tmp >> 8 + cyc = 6 * N + cyc += 2 + cycles cyc + upd78k2_interrupt local vector_addr 16 if cycles >=U int_cycle
--- a/upd78k2_util.c Fri Jul 11 10:55:33 2025 -0700 +++ b/upd78k2_util.c Sat Jul 12 22:25:20 2025 -0700 @@ -188,11 +188,27 @@ uint8_t upd78237_sfr_read(uint32_t address, void *context) { upd78k2_context *upd = context; - if (address < 8) { - return upd->port_data[address]; - } switch (address) { + case 0x00: + case 0x04: + case 0x05: + case 0x06: + return upd->port_data[address]; + case 0x02: + case 0x07: + //input only + if (upd->io_read) { + upd->io_read(upd, address); + } + return upd->port_input[address]; + break; + case 0x01: + case 0x03: + if (upd->io_read) { + upd->io_read(upd, address); + } + return (upd->port_input[address] & upd->port_mode[address]) | (upd->port_data[address] & ~upd->port_mode[address]); case 0x10: return upd->cr00; case 0x11: @@ -262,6 +278,9 @@ case 0x06: printf("P%X: %02X\n", address & 7, value); upd->port_data[address & 7] = value; + if (upd->io_write) { + upd->io_write(upd, address); + } break; case 0x10: upd78k2_update_timer0(upd); @@ -400,9 +419,11 @@ printf("ISM0: %04X\n", upd->ism0); break; case 0xF4: + printf("INTM0: %02X\n", value); upd->intm0 = value; break; case 0xF5: + printf("INTM1: %02X\n", value); upd->intm1 = value; break; case 0xF8:
--- a/upd78k2run.c Fri Jul 11 10:55:33 2025 -0700 +++ b/upd78k2run.c Sat Jul 12 22:25:20 2025 -0700 @@ -10,13 +10,13 @@ { } -uint8_t pram[384]; -uint8_t rom[0xFC80]; +uint8_t pram[768]; +uint8_t rom[0xFB00]; const memmap_chunk upd_map[] = { - { 0x0000, 0xFC80, 0xFFFFF, .flags = MMAP_READ, .buffer = rom}, - { 0xFC80, 0xFD00, 0x7F, .flags = MMAP_READ | MMAP_WRITE | MMAP_CODE, .buffer = pram}, - { 0xFD00, 0xFE00, 0xFF, .flags = MMAP_READ | MMAP_WRITE | MMAP_CODE, .buffer = pram + 128}, + { 0x0000, 0xFB00, 0xFFFFF, .flags = MMAP_READ, .buffer = rom}, + { 0xFB00, 0xFD00, 0x1FF, .flags = MMAP_READ | MMAP_WRITE | MMAP_CODE, .buffer = pram}, + { 0xFD00, 0xFE00, 0xFF, .flags = MMAP_READ | MMAP_WRITE | MMAP_CODE, .buffer = pram + 512}, { 0xFF00, 0xFFFF, 0xFF, .read_8 = upd78237_sfr_read, .write_8 = upd78237_sfr_write} }; @@ -64,6 +64,10 @@ fclose(f); init_upd78k2_opts(&opts, upd_map, 4); upd = init_upd78k2_context(&opts); + upd->port_input[2] = 0xFF; + upd->port_input[3] = 0x20; + upd->port_input[7] = 0xF7; + upd->pc = rom[0] | rom[1] << 8; upd78k2_execute(upd, 10000000); return 0;