Mercurial > repos > blastem
view zruntime.S @ 622:b76d2a628ab9
Partially working switch to having a vcounter and hslot counter in the context rather than trying to derive them from the cycle count. This should allow for more accurate handling of mid screen mode switches. Interrupt timing is broken currently though
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 17 Jun 2014 19:01:01 -0700 |
parents | b3738ee58195 |
children | 6b248602ab84 |
line wrap: on
line source
z_inccycles_io: cmp %edi, %ebp jnb do_limit no_sync_io: add $4, %ebp ret do_limit_io: cmp 112(%rsi), %ebp jb no_sync_io jmp sync_io z_inccycles: cmp %edi, %ebp jnb do_limit no_sync: add $3, %ebp ret do_limit: cmp 112(%rsi), %ebp jb no_sync sync_io: movw $0, 164(%rsi) call z80_save_context_scratch pop %rax /*return address in read/write func*/ pop 104(%rsi) /*return address in native code*/ sub $5, %rax /* adjust return addres to point to the call instruction that got us here */ mov %rax, (%rsi) pop %r15 /* restore callee saved regsiters */ pop %r14 pop %r13 pop %r12 pop %rbp pop %rbx ret /* return to caller of z80_run */ forced_sync: movw $0, 164(%rsi) call z80_save_context_scratch pop (%rsi) /*return address in read/write func*/ pop 104(%rsi) /*return address in native code*/ pop %r15 /* restore callee saved regsiters */ pop %r14 pop %r13 pop %r12 pop %rbp pop %rbx ret /* return to caller of z80_run */ .global z80_handle_cycle_limit_int z80_handle_cycle_limit_int: cmp 116(%rsi), %ebp jb zskip_int mov 112(%rsi), %ebp /* set cycle limit to sync cycle */ /* not sure this is really necessary now that IFF1 and IFF2 are geting cleared */ movl $0xFFFFFFFF, 116(%rsi) /* make sure the interrupt doesn't fire more than once */ /* disable interrupts */ movb $0, 96(%rsi) movb $0, 97(%rsi) add $7, %ebp sub $2, %r9w mov %r9w, %r14w call z_inccycles push %r13 call z80_write_byte_noinc pop %r13 mov %r9w, %r14w add $1, %r14w shr $8, %r13w call z_inccycles call z80_write_byte_noinc pop %r14 /*dispose of return address */ /* TODO: Support interrupt mode 0 and 2 */ mov $0x38, %r13w call z80_native_addr jmp *%r13 zskip_int: cmp 112(%rsi), %ebp jb zskip_sync mov %r13w, 164(%rsi) .global z80_do_sync z80_do_sync: call z80_save_context pop (%rsi) /*return address in native code*/ pop %r15 /* restore callee saved regsiters */ pop %r14 pop %r13 pop %r12 pop %rbp pop %rbx zskip_sync: ret .global z80_halt z80_halt: mov %edi, %r14d sub %ebp, %r14d and $0xFFFFFFFC, %r14d add %r14d, %ebp cmp %edi, %ebp jnb z80_handle_cycle_limit_int add $4, %ebp jmp z80_handle_cycle_limit_int .global z80_read_byte z80_read_byte: call z_inccycles z80_read_byte_noinc: cmp $0x4000, %r13w jb z80_read_ram cmp $0x8000, %r13w jae z80_read_bank cmp $0x6000, %r13w jb z80_read_ym2612 /* TODO: Bank reg, YM-2612, PSG/VDP */ mov $0xFF, %r13b ret z80_read_ram: and $0x1FFF, %r13 mov (%r11, %r13), %r13b ret z80_read_bank: /* approximation of wait states for normal 68K bus access */ add $3, %ebp push %rsi mov 144(%rsi), %rsi /* get system context pointer */ cmp $0, 120(%rsi) /* check bus busy flag */ pop %rsi jne bus_busy z80_read_bank_cont: and $0x7FFF, %r13 cmp $0, %r12 je slow_bank_read /* 68K memory is byte swapped */ xor $1, %r13 mov (%r12, %r13), %r13b ret slow_bank_read: /* TODO: Call into C to implement this */ ret bus_busy: cmp %ebp, %edi jbe no_adjust mov %edi, %ebp no_adjust: call forced_sync jmp z80_read_bank_cont z80_read_ym2612: call z80_save_context mov %r13w, %di push %rsi call z80_read_ym pop %rsi mov %al, %r13b call z80_load_context ret .global z80_write_byte z80_write_byte: call z_inccycles z80_write_byte_noinc: cmp $0x4000, %r14w jb z80_write_ram cmp $0x8000, %r14w jae z80_write_bank cmp $0x6000, %r14w jb z80_write_ym2612 cmp $0x6100, %r14w jb z80_write_bank_reg cmp $0x7F00, %r14w jae z80_write_vdp ret z80_write_ram: and $0x1FFF, %r14 mov %r13b, (%r11, %r14) mov %r14d, %r13d shr $7, %r13d bt %r13d, 152(%rsi) jnc not_code call z80_save_context mov %r14d, %edi call z80_handle_code_write mov %rax, %rsi call z80_load_context not_code: ret z80_write_bank: slow_bank_write: /* approximation of wait states for 68K bus access */ add $3, %ebp /* TODO: Call into C to implement this */ ret z80_write_ym2612: and $0x3, %r14w call z80_save_context mov %r14w, %di mov %r13b, %dl call z80_write_ym mov %rax, %rsi jmp z80_load_context z80_write_bank_reg: and $1, %r13w shr %r15w shl $8, %r13w xor %r12, %r12 or %r13w, %r15w and $0x1FF, %r15w cmp $0x80, %r15w jb update_bank_ptr ret update_bank_ptr: mov %r15w, %r12w shl $15, %r12 add 80(%rsi), %r12 ret z80_write_vdp: and $0xFF, %r14w call z80_save_context mov %r14w, %di mov %r13b, %dl call z80_vdp_port_write mov %rax, %rsi jmp z80_load_context .global z80_read_word z80_read_word: call z_inccycles cmp $0x8000, %r13w jae z80_read_bank_word push %r13 call z80_read_byte_noinc mov %r13b, %r14b pop %r13 inc %r13 call z_inccycles call z80_read_byte_noinc shl $8, %r13w mov %r14b, %r13b ret z80_read_bank_word: add $3, %ebp /* first read typically has 3 wait states */ push %rsi mov 144(%rsi), %rsi /* get system context pointer */ cmp $0, 120(%rsi) /* check bus busy flag */ pop %rsi jne bus_busy_word z80_read_bank_word_cont: push %r13 call z80_read_bank_cont mov %r13b, %r14b pop %r13 inc %r13 call z_inccycles add $4, %ebp /* second read typically has 4 wait states */ push %rsi mov 144(%rsi), %rsi /* get system context pointer */ cmp $0, 120(%rsi) /* check bus busy flag */ pop %rsi jne bus_busy_word2 z80_read_bank_word_cont2: call z80_read_bank_cont shl $8, %r13w mov %r14b, %r13b ret bus_busy_word: cmp %ebp, %edi jb no_adjust_word mov %edi, %ebp no_adjust_word: call forced_sync jmp z80_read_bank_word_cont foofoo: jmp foofoo bus_busy_word2: cmp %ebp, %edi jb no_adjust_word2 mov %edi, %ebp no_adjust_word2: call forced_sync jmp z80_read_bank_word_cont2 blahblah: jmp blahblah .global z80_write_word_highfirst z80_write_word_highfirst: call z_inccycles push %r14 push %r13 add $1, %r14w shr $8, %r13w call z80_write_byte_noinc pop %r13 pop %r14 call z_inccycles call z80_write_byte_noinc ret .global z80_write_word_lowfirst z80_write_word_lowfirst: call z_inccycles push %r14 push %r13 call z80_write_byte_noinc pop %r13 pop %r14 add $1, %r14w shr $8, %r13w call z_inccycles call z80_write_byte_noinc ret .global z80_io_read z80_io_read: call z_inccycles_io /* genesis Z80 has no IO port hardware and always returns FF */ mov $0xFF, %r13 ret .global z80_io_write z80_io_write: call z_inccycles_io /* genesis Z80 has no IO port hardware and writes have no effect */ ret .global z80_retrans_stub z80_retrans_stub: pop %r14 call z80_save_context /* adjust for mov and call instructions */ sub $11, %r14 mov %r13d, %edi mov %r14, %rdx push %rsi call z80_retranslate_inst pop %rsi mov %rax, %r13 call z80_load_context jmp *%r13 .global z80_native_addr z80_native_addr: call z80_save_context push %rsi mov %rsi, %rdi movzx %r13w, %esi call z80_get_native_address_trans mov %rax, %r13 pop %rsi call z80_load_context ret z80_save_context_scratch: mov %r13w, 98(%rsi) /* scratch1 */ mov %r14w, 100(%rsi) /* scratch2 */ .global z80_save_context z80_save_context: mov %r9w, 8(%rsi) /* SP */ mov %r15w, 16(%rsi) /* bank register */ mov %bx, 18(%rsi) /* BC */ mov %cx, 20(%rsi) /* DE */ mov %ax, 22(%rsi) /* HL */ mov %dx, 24(%rsi) /* IX */ mov %r8w, 26(%rsi) /* IY */ mov %r10b, 30(%rsi) /* A */ mov %edi, 48(%rsi) /* target_cycle */ mov %ebp, 52(%rsi) /* current_cycle */ mov %r12, 72(%rsi) /* cartridge bank pointer */ ret z80_load_context_scratch: mov 98(%rsi), %r13w /* scratch1 */ mov 100(%rsi), %r14w /* scratch2 */ .global z80_load_context z80_load_context: mov 8(%rsi), %r9w /* SP */ mov 16(%rsi), %r15w /* bank register */ mov 18(%rsi), %bx /* BC */ mov 20(%rsi), %cx /* DE */ mov 22(%rsi), %ax /* HL */ mov 24(%rsi), %dx /* IX */ mov 26(%rsi), %r8w /* IY */ mov 30(%rsi), %r10b /* A */ mov 48(%rsi), %edi /* target_cycle */ mov 52(%rsi), %ebp /* current_cycle */ mov 64(%rsi), %r11 /* z80 RAM */ mov 72(%rsi), %r12 /* cartridge bank pointer */ ret .global z80_run z80_run: push %rbx push %rbp push %r12 push %r13 push %r14 push %r15 mov %rdi, %rsi call z80_load_context_scratch cmpq $0, 104(%rsi) je no_extra push 104(%rsi) movq $0, 104(%rsi) no_extra: jmp *(%rsi)