Mercurial > repos > blastem
changeset 2714:d30e7f605ff8
Get uPD78k/II timer interrupts actually working and implement instructions needed for them to run to completion
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 10 Jul 2025 20:27:49 -0700 |
parents | a88eff3fb5d8 |
children | 8d4ee0c04ee0 |
files | cpu_dsl.py upd78k2.cpu upd78k2_util.c |
diffstat | 3 files changed, 179 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/cpu_dsl.py Thu Jul 10 16:07:04 2025 -0700 +++ b/cpu_dsl.py Thu Jul 10 20:27:49 2025 -0700 @@ -1253,7 +1253,12 @@ return ret def _updateSyncCImpl(prog, params): - return '\n\t{sync}(context, target_cycle);'.format(sync=prog.sync_cycle) + ret = '' + if prog.needFlagDisperse: + ret += prog.flags.disperseFlags(prog, 'c') + prog.needFlagDispserse = False + ret += f'\n\t{prog.sync_cycle}(context, target_cycle);' + return ret _opMap = { 'mov': Op(lambda val: val).cUnaryOperator(''),
--- a/upd78k2.cpu Thu Jul 10 16:07:04 2025 -0700 +++ b/upd78k2.cpu Thu Jul 10 20:27:49 2025 -0700 @@ -280,24 +280,28 @@ end mem_write_no_exp full_address value +push_byte + arg value 8 + sp -= 1 + mem_write_no_exp sp value + push_word arg value 16 local tmp 8 tmp = value >> 8 - sp -= 1 - mem_write_no_exp sp tmp - tmp = value - sp -= 1 - mem_write_no_exp sp tmp + push_byte tmp + push_byte value + +pop_byte + mem_read_no_exp sp + sp += 1 pop_word - mem_read_no_exp sp + pop_byte dst = scratch1 - sp += 1 - mem_read_no_exp sp + pop_byte scratch1 <<= 8 dst |= scratch1 - sp += 1 00000000 nop cycles 2 #minimum cycle time appears to be 4 (ignoring internal divider) @@ -401,6 +405,26 @@ #TODO: what happens in these invalid cases end +aluop16_ax + local tmp 16 + arg op 8 + arg src 16 + tmp = a << 8 + tmp |= x + switch op + case 1 + tmp += src + update_flags ZAC + case 2 + tmp -= src + update_flags ZAC + case 3 + tmp -= src + update_flags ZAC + end + x = tmp + a = tmp >> 8 + 10001PPP alu_r_r local tmp_src 16 local tmp_dst 16 @@ -457,6 +481,39 @@ meta dst scratch1 aluop P immed saddr_write offset scratch1 + +001011PP alu_ax_immed + invalid P 0 + upd78k2_op_fetch_word + aluop16_ax P scratch1 + +000111PP alu_ax_saddr + invalid P 0 + local offset 8 + local tmp 8 + upd78k2_op_fetch + offset = scratch1 + saddr_read offset + tmp = scratch1 + offset += 1 + saddr_read offset + scratch1 <<= 16 + scratch1 |= tmp + aluop16_ax P scratch1 + +sfr 000111PP alu_ax_sfr + invalid P 0 + local offset 8 + local tmp 8 + upd78k2_op_fetch + offset = scratch1 + sfr_read offset + tmp = scratch1 + offset += 1 + sfr_read offset + scratch1 <<= 16 + scratch1 |= tmp + aluop16_ax P scratch1 calc_addr_base arg regpair 8 @@ -733,6 +790,62 @@ scratch2 = scratch1 mem_write_no_exp scratch2 a +00100000 mov_a_saddr + upd78k2_op_fetch + saddr_read scratch1 + a = scratch1 + +00100010 mov_saddr_a + upd78k2_op_fetch + scratch2 = scratch1 + saddr_write scratch2 a + +00010000 mov_a_sfr + upd78k2_op_fetch + sfr_read scratch1 + a = scratch1 + +00010010 mov_sfr_a + upd78k2_op_fetch + scratch2 = scratch1 + sfr_write scratch2 a + +00011100 mov_ax_saddr + local offset 8 + upd78k2_op_fetch + offset = scratch1 + saddr_read offset + x = scratch1 + offset += 1 + saddr_read offset + a = scratch1 + +00011010 mov_saddr_ax + local offset 8 + upd78k2_op_fetch + offset = scratch1 + saddr_write offset x + offset += 1 + saddr_write offset a + +00010001 mov_ax_saddr + local offset 8 + upd78k2_op_fetch + offset = scratch1 + sfr_read offset + x = scratch1 + offset += 1 + sfr_read offset + a = scratch1 + +00010011 mov_saddr_ax + local offset 8 + upd78k2_op_fetch + offset = scratch1 + sfr_write offset x + offset += 1 + sfr_write offset a + 11000RRR inc_r cycles 2 main.R += 1 @@ -743,6 +856,24 @@ main.R -= 1 update_flags ZA +00100110 inc_saddr + local offset 8 + upd78k2_op_fetch + offset = scratch1 + saddr_read offset + add scratch1 1 scratch1 0 + update_flags ZA + saddr_write offset scratch1 + +00100111 dec_saddr + local offset 8 + upd78k2_op_fetch + offset = scratch1 + saddr_read offset + sub scratch1 1 scratch1 0 + update_flags ZA + saddr_write offset scratch1 + 11010RRR mov_a_r a = main.R @@ -1241,16 +1372,32 @@ scratch1 &= mask saddr_write offset scratch1 +01010111 reti + meta dst pc + pop_word + pop_byte + psw = scratch1 + update_sync + upd78k2_interrupt + local vector_addr 16 if cycles >=U int_cycle update_sync if int_enable scratch1 = ~mk0 scratch1 &= if0 if != + push_byte psw + push_word pc ocall calc_vector - mem_read_no_exp scratch1 + vector_addr = scratch1 + mem_read_no_exp vector_addr pc = scratch1 + vector_addr += 1 + mem_read_no_exp vector_addr + scratch1 <<= 8 + pc |= scratch1 + int_enable = 0 end end end
--- a/upd78k2_util.c Thu Jul 10 16:07:04 2025 -0700 +++ b/upd78k2_util.c Thu Jul 10 20:27:49 2025 -0700 @@ -193,6 +193,18 @@ } switch (address) { + case 0x10: + return upd->cr00; + case 0x11: + return upd->cr00 >> 8; + case 0x12: + return upd->cr01; + case 0x13: + return upd->cr01 >> 8; + case 0x14: + return upd->cr10; + case 0x1C: + return upd->cr11; case 0x21: case 0x26: return upd->port_mode[address & 0x7]; @@ -269,7 +281,7 @@ upd78k2_update_timer0(upd); upd->cr01 &= 0xFF00; upd->cr01 |= value; - printf("CR01: %04X\n", upd->cr00); + printf("CR01: %04X\n", upd->cr01); upd78k2_calc_next_int(upd); break; case 0x13: @@ -438,12 +450,15 @@ { uint32_t pending_enabled = upd->scratch1; uint32_t vector = 0x6; + uint32_t bit = 1; while (pending_enabled) { if (pending_enabled & 1) { + upd->if0 &= ~bit; upd->scratch1 = vector; return; } + bit <<= 1; pending_enabled >>= 1; vector += 2; if (vector == 0xE) {