mirror of
https://github.com/libretro/blastem.git
synced 2026-11-09 17:21:56 -10:00
438 lines
8.2 KiB
ArmAsm
438 lines
8.2 KiB
ArmAsm
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 */
|
|
cmpb $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
|
|
test $8, %rsp
|
|
jnz 0f
|
|
call z80_read_ym
|
|
jmp 1f
|
|
0:
|
|
sub $8, %rsp
|
|
call z80_read_ym
|
|
add $8, %rsp
|
|
1:
|
|
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
|
|
test $8, %rsp
|
|
jnz 0f
|
|
call z80_write_ym
|
|
jmp 1f
|
|
0:
|
|
sub $8, %rsp
|
|
call z80_write_ym
|
|
add $8, %rsp
|
|
1:
|
|
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
|
|
test $8, %rsp
|
|
jnz 0f
|
|
call z80_vdp_port_write
|
|
jmp 1f
|
|
0:
|
|
sub $8, %rsp
|
|
call z80_vdp_port_write
|
|
add $8, %rsp
|
|
1:
|
|
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 */
|
|
cmpb $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 */
|
|
cmpb $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)
|
|
|