.DATA ;@ Reesy's Z80 Emulator Version 0.001 ;@ (c) Copyright 2004 Reesy, All rights reserved ;@ DrZ80 is free for non-commercial use. ;@ For commercial use, separate licencing terms must be obtained. .global DrZ80Run .global DrZ80Ver .equiv INTERRUPT_MODE, 0 ;@0 = Use internal int handler, 1 = Use Mames int handler .equiv FAST_Z80SP, 1 ;@0 = Use mem functions for stack pointer, 1 = Use direct mem pointer .equiv GNGEO_OPTIM, 1 ;@0 = Use mem handler and rebase pc/sp, 1 = Use optim for gngeo .if INTERRUPT_MODE .extern Interrupt .endif DrZ80Ver: .long 0x0001 ;@--------------------------------------- .macro fetch cycs subs z80_icount,z80_icount,#\cycs ldrplb r0,[z80pc],#1 ldrpl pc,[opcodes,r0, lsl #2] bmi z80_execute_end .endm .macro eatcycles cycs sub z80_icount,z80_icount,#\cycs .endm .if GNGEO_OPTIM .macro readmem8 ldr r1,[cpucontext,#z80pc_base] ldrb r0,[r1,r0] .endm .macro readmem8HL ldr r1,[cpucontext,#z80pc_base] ldrb r0,[r1,z80hl, lsr #16] .endm .macro readmem16 ldr r1,[cpucontext,#z80pc_base] ldrb r2,[r0,r1]! ldrb r0,[r0, #1] orr r0,r2, r0, lsl #8 .endm .macro writemem8 ldr r2,[cpucontext,#z80pc_base] strb r0,[r2,r1] .endm ;@ TODO @.macro writemem16 @ ldr r2,[cpucontext,#z80pc_base] @ strb r1,[r0,r2]! @ mov r1, r1, lsr #8 @ strb r1,[r0,#1] @.endm .macro writemem16 stmfd sp!,{r3,r12} mov lr,pc ldr pc,[cpucontext,#z80_write16] ;@ r0=data r1=addr ldmfd sp!,{r3,r12} .endm .else .macro readmem8 stmfd sp!,{r3,r12} mov lr,pc ldr pc,[cpucontext,#z80_read8] ;@ r0 = addr - data returned in r0 ldmfd sp!,{r3,r12} .endm .macro readmem8HL mov r0,z80hl, lsr #16 readmem8 .endm .macro readmem16 stmfd sp!,{r3,r12} mov lr,pc ldr pc,[cpucontext,#z80_read16] ldmfd sp!,{r3,r12} .endm .macro writemem8 stmfd sp!,{r3,r12} mov lr,pc ldr pc,[cpucontext,#z80_write8] ;@ r0=data r1=addr ldmfd sp!,{r3,r12} .endm .macro writemem16 stmfd sp!,{r3,r12} mov lr,pc ldr pc,[cpucontext,#z80_write16] ;@ r0=data r1=addr ldmfd sp!,{r3,r12} .endm .endif .macro writemem8DE mov r1,z80de, lsr #16 writemem8 .endm .macro writemem8HL mov r1,z80hl, lsr #16 writemem8 .endm .macro copymem8HL_DE mov r0,z80hl, lsr #16 stmfd sp!,{r3,r12} mov lr,pc ldr pc,[cpucontext,#z80_read8] ;@ r0 = addr - data returned in r0 mov r1,z80de, lsr #16 mov lr,pc ldr pc,[cpucontext,#z80_write8] ;@ r0=data r1=addr ldmfd sp!,{r3,r12} .endm ;@--------------------------------------- .if GNGEO_OPTIM .macro rebasepc ldr r1,[cpucontext,#z80pc_base] add z80pc,r0,r1 .endm .else .macro rebasepc stmfd sp!,{r3,r12} mov lr,pc ldr pc,[cpucontext,#z80_rebasePC] ;@ r0=new pc - external function sets z80pc_base and returns new z80pc in r0 ldmfd sp!,{r3,r12} mov z80pc,r0 .endm .endif .if GNGEO_OPTIM .macro rebasesp ldr r1,[cpucontext,#z80sp_base] add z80sp,r0,r1 .endm .else .macro rebasesp stmfd sp!,{r3,r12} mov lr,pc ldr pc,[cpucontext,#z80_rebaseSP] ;@ external function must rebase sp ldmfd sp!,{r3,r12} mov z80sp,r0 .endm .endif ;@---------------------------------------------------------------------------- .macro opADC movs z80f,z80f,lsr#2 ;@ get C subcs r0,r0,#0x100 eor z80f,r0,z80a,lsr#24 ;@ prepare for check of half carry adcs z80a,z80a,r0,ror#8 mrs r0,cpsr ;@ S,Z,V&C eor z80f,z80f,z80a,lsr#24 and z80f,z80f,#1< 0xFF writemem8HL add z80hl,z80hl,#1<<16 sub z80bc,z80bc,#1<<24 tst z80bc,#0xFF<<24 orrmi z80f,z80f,#1< 0xFF sub z80bc,z80bc,#1<<24 tst z80bc,#0xFF<<24 orrmi z80f,z80f,#1< 0xFF writemem8HL sub z80hl,z80hl,#1<<16 sub z80bc,z80bc,#1<<24 tst z80bc,#0xFF<<24 orrmi z80f,z80f,#1< 0xFF sub z80bc,z80bc,#1<<24 tst z80bc,#0xFF<<24 orrmi z80f,z80f,#1< 0xFF writemem8HL add z80hl,z80hl,#1<<16 sub z80bc,z80bc,#1<<24 tst z80bc,#0xFF<<24 orrmi z80f,z80f,#1< 0xFF sub z80bc,z80bc,#1<<24 tst z80bc,#0xFF<<24 orrmi z80f,z80f,#1< 0xFF writemem8HL sub z80hl,z80hl,#1<<16 sub z80bc,z80bc,#1<<24 tst z80bc,#0xFF<<24 orrmi z80f,z80f,#1< 0xFF sub z80bc,z80bc,#1<<24 tst z80bc,#0xFF<<24 orrmi z80f,z80f,#1<