⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drz80.asm

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;@---------------------------------------

	MACRO 
		opRR $reg1, $reg2, $shift
			movs $reg1,$reg2,lsr #$shift
			tst z80f,#1<<CFlag						;@doesn't affect ARM carry, as long as the imidiate value is < 0x100. Watch out!
			orrne $reg1,$reg1,#0x00000080
		;@	and r2,z80_f,#PSR_C
		;@	orr $reg1,$reg1,r2,lsl #6
			sub r1,opcodes,#0x100
			ldrb z80f,[r1,$reg1]
			orrcs z80f,z80f,#1<<CFlag
	MEND

	MACRO 
		opRRA
			orr z80a,z80a,z80f,lsr #1				;@get C
			movs z80a,z80a,ror #25
			mov z80a,z80a,lsl #24
			sub r1,opcodes,#0x100
			ldrb z80f,[r1,z80a,lsr #24]
			orrcs z80f,z80f,#1<<CFlag
			fetch 8
	MEND

	MACRO 
		opRRH $reg
			orr r0,$reg,z80f,lsr #1					;@get C
			movs r0,r0,ror #25
			and $reg,$reg,#0x00FF0000				;@mask out low
			orr $reg,$reg,r0,lsl #24
			sub r1,opcodes,#0x100
			ldrb z80f,[r1,$reg,lsr #24]
			orrcs z80f,z80f,#1<<CFlag
			fetch 8
	MEND

	MACRO 
		opRRL $reg
			and r0,$reg,#0x00FF0000					;@mask out low to r0
			opRR r0, r0, 17
			and $reg,$reg,#0xFF000000				;@mask out high
			orr $reg,$reg,r0,lsl #16
			fetch 8
	MEND

	MACRO 
		opRRb
			opRR r0, r0, 1
	MEND

;@---------------------------------------

	MACRO 
		opRRC $reg1, $reg2, $shift
			movs $reg1,$reg2,lsr #$shift
			orrcs $reg1,$reg1,#0x00000080
			sub r1,opcodes,#0x100
			ldrb z80f,[r1,$reg1]
			orrcs z80f,z80f,#1<<CFlag
	MEND
	
	MACRO 
		opRRCA
			opRRC z80a, z80a, 25
			mov z80a,z80a,lsl #24
			fetch 8
	MEND

	MACRO 
		opRRCH $reg
			opRRC r0, $reg, 25
			and $reg,$reg,#0x00FF0000				;@mask out low
			orr $reg,$reg,r0,lsl #24
			fetch 8
	MEND
	
	MACRO 
		opRRCL $reg
			and r0,$reg,#0x00FF0000					;@mask low to r0
			opRRC r0, r0, 17
			and $reg,$reg,#0xFF000000				;@mask out high
			orr $reg,$reg,r0,lsl #16
			fetch 8
	MEND

	MACRO 
		opRRCb
			opRRC r0, r0, 1
	MEND

;@---------------------------------------

	MACRO 
		opRST $addr
			ldr r0,[cpucontext,#z80pc_base]
			sub r0,z80pc,r0
			 IF FAST_Z80SP
				mov r1,r0, lsr #8
				strb r1,[z80sp,#-1]!
				strb r0,[z80sp,#-1]!
			 ELSE
				sub z80sp,z80sp,#2
				mov r1,z80sp
				writemem16
			 ENDIF
			mov r0,#$addr
			rebasepc
			fetch 11
	MEND

;@---------------------------------------

	MACRO 
		opSBC
			eor z80f,z80f,#1<<CFlag					;@ invert C
			movs z80f,z80f,lsr #2					;@ get C
			subcc r0,r0,#0x100
			eor z80f,r0,z80a,lsr #24					;@ prepare for check of H
			sbcs z80a,z80a,r0,ror #8
			mrs r0,cpsr
			eor z80f,z80f,z80a,lsr #24
			and z80f,z80f,#1<<HFlag					;@ H, correct
			orr z80f,z80f,r0,lsr #28					;@ S,Z,V&C
			eor z80f,z80f,#(1<<CFlag)|(1<<NFlag)	;@ invert C and set n.
	MEND

	MACRO 
		opSBCA
			movs z80f,z80f,lsr #2					;@ get C
			movcc z80a,#0x00000000
			movcs z80a,#0xFF000000
			movcc z80f,#(1<<NFlag)|(1<<ZFlag)
			movcs z80f,#58
			fetch 4
	MEND
	
	MACRO 
		opSBCH $reg
			mov r0,$reg,lsr #24
			opSBC
			fetch 4
	MEND

	MACRO 
		opSBCL $reg
			mov r0,$reg,lsl #8
			eor z80f,z80f,#1<<CFlag					;@ invert C
			movs z80f,z80f,lsr #2					;@ get C
			sbccc r0,r0,#0xFF000000
			mov r1,z80a,lsl #4						;@ prepare for check of H
			sbcs z80a,z80a,r0
			mrs z80f,cpsr
			mov z80f,z80f,lsr #28					;@ S,Z,V&C
			eor z80f,z80f,#(1<<CFlag)|(1<<NFlag)	;@ invert C and set n.
			cmp r1,r0,lsl #4
			orrcc z80f,z80f,#1<<HFlag				;@ H, correct
			fetch 4
	MEND

	MACRO 
		opSBCb
			opSBC
	MEND

;@---------------------------------------

	MACRO 
		opSBC16 $reg
			eor z80f,z80f,#1<<CFlag					;@ invert C
			movs z80f,z80f,lsr #2					;@ get C
			sbc r1,r1,r1							;@ set r1 to -1 or 0.
			orr r0,$reg,r1,lsr #16
			mov r1,z80hl,lsl #4						;@ prepare for check of H
			sbcs z80hl,z80hl,r0
			mrs z80f,cpsr
			mov z80f,z80f,lsr #28					;@ S,Z,V&C
			eor z80f,z80f,#(1<<CFlag)|(1<<NFlag)	;@ invert C and set n.
			cmp r1,r0,lsl #4
			orrcc z80f,z80f,#1<<HFlag				;@ H, correct
			fetch 15
	MEND

	MACRO 
		opSBC16HL
			movs z80f,z80f,lsr #2					;@ get C
			mov z80hl,#0x00000000
			subcs z80hl,z80hl,#0x00010000
			movcc z80f,#(1<<NFlag)|(1<<ZFlag)
			movcs z80f,#58
			fetch 15
	MEND
	
;@---------------------------------------

	MACRO 
		opSETmemHL $bit
			mov r0,z80hl, lsr #16
			stmfd sp!,{r3,r12}
			mov lr,pc
			ldr pc,[cpucontext,#z80_read8]			;@ r0 = addr - data returned in r0
			orr r0,r0,#1<<$bit
			mov r1,z80hl, lsr #16
			mov lr,pc
			ldr pc,[cpucontext,#z80_write8]			;@ r0=data r1=addr
			ldmfd sp!,{r3,r12}
			fetch 15
	MEND

;@---------------------------------------

	MACRO 
		opSETmem $bit
			stmfd sp!,{r3,r12}
			stmfd sp!,{r0}	;@ save addr as well
			mov lr,pc
			ldr pc,[cpucontext,#z80_read8]			;@ r0=addr - data returned in r0
			orr r0,r0,#1<<$bit
			ldmfd sp!,{r1}	;@ restore addr into r1
			mov lr,pc
			ldr pc,[cpucontext,#z80_write8]			;@ r0=data r1=addr
			ldmfd sp!,{r3,r12}
			fetch 23
	MEND

;@---------------------------------------

	MACRO 
		opSLA $reg1, $reg2, $shift
			movs $reg1,$reg2,lsl #$shift
			sub r1,opcodes,#0x100
			ldrb z80f,[r1,$reg1,lsr #24]
			orrcs z80f,z80f,#1<<CFlag
	MEND

	MACRO 
		opSLAA
			opSLA z80a, z80a, 1
			fetch 8
	MEND

	MACRO 
		opSLAH $reg
			and r0,$reg,#0xFF000000					;@mask high to r0
			adds $reg,$reg,r0
			sub r1,opcodes,#0x100
			ldrb z80f,[r1,$reg,lsr #24]
			orrcs z80f,z80f,#1<<CFlag
			fetch 8
	MEND
	
	MACRO 
		opSLAL $reg
			opSLA r0, $reg, 9
			and $reg,$reg,#0xFF000000				;@mask out high
			orr $reg,$reg,r0,lsr #8
			fetch 8
	MEND

	MACRO
		opSLAb
			opSLA r0, r0, 25
			mov r0,r0,lsr #24
	MEND

;@---------------------------------------

	MACRO
		opSLL $reg1, $reg2, $shift
			movs $reg1,$reg2,lsl #$shift
			orr $reg1,$reg1,#0x01000000
			sub r1,opcodes,#0x100
			ldrb z80f,[r1,$reg1,lsr #24]
			orrcs z80f,z80f,#1<<CFlag
	MEND

	MACRO 
		opSLLA
			opSLL z80a, z80a, 1
			fetch 8
	MEND
	
	MACRO 
		opSLLH $reg
			and r0,$reg,#0xFF000000					;@mask high to r0
			adds $reg,$reg,r0
			orr $reg,$reg,#0x01000000
			sub r1,opcodes,#0x100
			ldrb z80f,[r1,$reg,lsr #24]
			orrcs z80f,z80f,#1<<CFlag
			fetch 8
	MEND
	
	MACRO 
		opSLLL $reg
			opSLL r0, $reg, 9
			and $reg,$reg,#0xFF000000				;@mask out high
			orr $reg,$reg,r0,lsr #8
			fetch 8
	MEND
	
	MACRO 
		opSLLb
			opSLL r0, r0, 25
			mov r0,r0,lsr #24
	MEND

;@---------------------------------------

	MACRO 
		opSRA $reg1, $reg2
			movs $reg1,$reg2,asr #25
			and $reg1,$reg1,#0xFF
			sub r1,opcodes,#0x100
			ldrb z80f,[r1,$reg1]
			orrcs z80f,z80f,#1<<CFlag
	MEND
	
	MACRO 
		opSRAA
			movs r0,z80a,asr #25
			mov z80a,r0,lsl #24
			sub r1,opcodes,#0x100
			ldrb z80f,[r1,z80a,lsr #24]
			orrcs z80f,z80f,#1<<CFlag
			fetch 8
	MEND

	MACRO 
		opSRAH $reg
			movs r0,$reg,asr #25
			and $reg,$reg,#0x00FF0000				;@mask out low
			orr $reg,$reg,r0,lsl #24
			sub r1,opcodes,#0x100
			ldrb z80f,[r1,$reg,lsr #24]
			orrcs z80f,z80f,#1<<CFlag
			fetch 8
	MEND

	MACRO
		opSRAL $reg
			mov r0,$reg,lsl #8
			opSRA r0, r0
			and $reg,$reg,#0xFF000000				;@mask out high
			orr $reg,$reg,r0,lsl #16
			fetch 8
	MEND

	MACRO
		opSRAb
			mov r0,r0,lsl #24
			opSRA r0, r0
	MEND

;@---------------------------------------

	MACRO 
		opSRL $reg1, $reg2, $shift
			movs $reg1,$reg2,lsr #$shift
			sub r1,opcodes,#0x100
			ldrb z80f,[r1,$reg1]
			orrcs z80f,z80f,#1<<CFlag
	MEND
	
	MACRO 
		opSRLA
			opSRL z80a, z80a, 25
			mov z80a,z80a,lsl #24
		fetch 8
	MEND
	
	MACRO 
		opSRLH $reg
			opSRL r0, $reg, 25
			and $reg,$reg,#0x00FF0000				;@mask out low
			orr $reg,$reg,r0,lsl #24
			fetch 8
	MEND
	
	MACRO 
		opSRLL $reg
			mov r0,$reg,lsl #8
			opSRL r0, r0, 25
			and $reg,$reg,#0xFF000000				;@mask out high
			orr $reg,$reg,r0,lsl #16
			fetch 8
	MEND
	
	MACRO 
		opSRLb
			opSRL r0, r0, 1
	MEND
	
;@---------------------------------------

	MACRO 
		opSUB $reg, $shift
			mov r1,z80a,lsl #4 						;@ Prepare for check of half carry
			subs z80a,z80a,$reg,lsl #$shift
			mrs z80f,cpsr
			mov z80f,z80f,lsr #28					;@ S,Z,V&C
			eor z80f,z80f,#(1<<CFlag)|(1<<NFlag)	;@ invert C and set n
			cmp r1,$reg,lsl #$shift+4
			orrcc z80f,z80f,#1<<HFlag
	MEND

	MACRO 
		opSUBA
			mov z80a,#0
			mov z80f,#(1<<ZFlag)|(1<<NFlag)			;@ set Z & n
			fetch 4
	MEND

	MACRO 
		opSUBH $reg
			and r0,$reg,#0xFF000000
			opSUB r0, 0
			fetch 4
	MEND

	MACRO
		opSUBL $reg
			opSUB $reg, 8
			fetch 4
	MEND

	MACRO 
		opSUBb
			opSUB r0, 24
	MEND

;@---------------------------------------

	MACRO 
		opXOR $reg, $shift
			eor z80a,z80a,$reg,lsl #$shift
			sub r0,opcodes,#0x100
			ldrb z80f,[r0,z80a, lsr #24]
	MEND

	MACRO
		opXORA
			mov z80a,#0
			mov z80f,#(1<<ZFlag)|(1<<VFlag)
			fetch 4
	MEND

	MACRO
		opXORH $reg
			and r0,$reg,#0xFF000000
			opXOR r0, 0
			fetch 4
	MEND

	MACRO 
		opXORL $reg
			opXOR $reg, 8
			fetch 4
	MEND

	MACRO
		opXORb
			opXOR r0, 24
	MEND
	
;@---------------------------------------


;@ --------------------------- Defines ----------------------------
;@ Make sure that regs/pointers for z80pc to z80sp match up!

opcodes			RN	3
z80_icount	RN	4
cpucontext	RN	5
z80pc				RN	6
z80a				RN	7
z80f				RN	8
z80bc				RN	9
z80de				RN	10
z80hl				RN	11
z80sp				RN	12	
z80xx				RN	lr


z80pc_pointer			EQU 0                  ;@  0
z80a_pointer			EQU z80pc_pointer+4    ;@  4
z80f_pointer			EQU z80a_pointer+4     ;@  8
z80bc_pointer			EQU z80f_pointer+4     ;@  
z80de_pointer			EQU z80bc_pointer+4
z80hl_pointer			EQU z80de_pointer+4
z80sp_pointer			EQU z80hl_pointer+4
z80pc_base				EQU z80sp_pointer+4
z80sp_base				EQU z80pc_base+4
z80ix							EQU z80sp_base+4
z80iy							EQU z80ix+4
z80i							EQU z80iy+4
z80a2							EQU z80i+4
z80f2							EQU z80a2+4
z80bc2						EQU z80f2+4
z80de2						EQU z80bc2+4
z80hl2						EQU z80de2+4
cycles_pointer		EQU z80hl2+4     
previouspc				EQU cycles_pointer+4     
z80irq						EQU previouspc+4
z80if							EQU z80irq+1
z80im							EQU z80if+1
z80r							EQU z80im+1
z80irqvector			EQU z80r+1
z80irqcallback		EQU z80irqvector+4
z80_write8				EQU z80irqcallback+4
z80_write16				EQU z80_write8+4
z80_in						EQU z80_write16+4
z80_out						EQU z80_in+4
z80_read8					EQU z80_out+4
z80_read16				EQU z80_read8+4
z80_rebaseSP			EQU z80_read16+4
z80_rebasePC			EQU z80_rebaseSP+4

VFlag					EQU		0
CFlag					EQU		1
ZFlag					EQU		2
SFlag					EQU		3
HFlag					EQU		4
NFlag					EQU		5
Flag3					EQU		6
Flag5					EQU		7

Z80_CFlag			EQU		0
Z80_NFlag			EQU		1
Z80_VFlag			EQU		2
Z80_Flag3			EQU		3
Z80_HFlag			EQU		4
Z80_Flag5			EQU		5
Z80_ZFlag			EQU		6
Z80_SFlag			EQU		7

Z80_IF1			EQU		1<<0
Z80_IF2			EQU		1<<1
Z80_HALT			EQU		1<<2

;@ --------------------------- Framework --------------------------
    
DrZ80Run	PROC

	;@ r0 = pointer to cpu context
	;@ r1 = ISTATES to execute  
	;@#########################################   
	stmdb sp!,{r4-r12,lr}					;@ save registers on stack
	mov cpucontext,r0						;@ setup main memory pointer
	mov z80_icount,r1						;@ setup number of Tstates to execute
	ldmia cpucontext,{z80pc-z80sp}			;@ load Z80 registers


	ldr opcodes,MAIN_opcodes_POINTER2

	 IF INTERRUPT_MODE = 0
	;@ check ints
		bl DoInterrupt  ;@ done in mame now
	 ENDIF

	ldrb r0,[z80pc],#1    ;@ get first op code
	ldr pc,[opcodes,r0, lsl #2]  ;@ execute op code

MAIN_opcodes_POINTER2 DCD MAIN_opcodes


z80_execute_end
	;@ save registers in CPU context
	stmia cpucontext,{z80pc-z80sp}			;@ save Z80 registers
	ldmia sp!,{r4-r12,pc}					;@ restore registers from stack and return to C code

	 IF INTERRUPT_MODE
Interrupt_local 
			DCD Interrupt
	 ENDIF

DoInterrupt
  IF INTERRUPT_MODE
	;@ Don't do own int handler, call mames instead

	;@ save everything back into DrZ80 context
	stmia cpucontext,{z80pc-z80sp}			;@ save Z80 registers
	stmfd sp!,{r3,r4,r5,lr}					;@ save rest of regs on stack
	mov lr,pc
	ldr pc,Interrupt_local
	ldmfd sp!,{r3,r4,r5,lr}					;@ load regs from stack
	;@ reload regs from DrZ80 context
	ldmia cpucontext,{z80pc-z80sp}			;@ load Z80 registers
	mov pc,lr ;@ return
  ELSE
	ldrb r0,[cpucontext,#z80irq]
	tst r0,r0
	moveq pc,lr
	ldrb r0,[cpucontext,#z80if]
	tst r0,#1
	moveq pc,lr ;@ exit  IF int disabled

	stmfd sp!,{lr}

	tst r0,#4 ;@ check halt
	addne z80pc,z80pc,#1

	;@ clear halt and int flags
	eor r0,r0,r0
	strb r0,[cpucontext,#z80if]

	;@ now check int mode
	ldrb r0,[cpucontext,#z80im]
	and r0,r0,#3
	ldr pc,[pc,r0,lsl #2]
	DCD 0
	DCD DoInterrupt_mode0
	DCD DoInterrupt_mode1
	DCD DoInterrupt_mode2
	DCD DoInterrupt_mode1

DoInterrupt_mode0
	;@ get 3 byte vector
	ldr r2,[cpucontext, #z80irqvector]
	and r1,r2,#0xFF0000
	cmp r1,#0xCD0000  ;@ call
	bne 1f
	;@ ########
	;@ # call
	;@ ########
	;@ save current pc on stack
	ldr r0,[cpucontext,#z80pc_base]
	sub r0,z80pc,r0
 IF FAST_Z80SP
	mov r1,r0, lsr #8
	strb r1,[z80sp,#-1]!
	strb r0,[z80sp,#-1]!
 ELSE
	sub z80sp,z80sp,#2
	mov r1,z80sp
	writemem16
	ldr r2,[cpucontext, #z80irqvector]
 ENDIF
	;@ jump to vector
	mov r2,r2,lsl #16
	mov r0,r2,lsr #16
	;@ rebase new pc
	rebasepc

	b DoInterrupt_end

1
	cmp r1,#0xC30000  ;@ jump
	bne DoInterrupt_mode1    ;@ rst
	;@ #######
	;@ # jump
	;@ #######
	;@ jump to vector
	mov r2,r2,lsl #16
	mov r0,r2,lsr #16
	;@ rebase new pc
	rebasepc

	b DoInterrupt_end

DoInterrupt_mode1
	ldr r0,[cpucontext,#z80pc_base]
	sub r0,z80pc,r0
 IF FAST_Z80SP
	mov r1,r0, lsr #8
	strb r1,[z80sp,#-1]!
	strb r0,[z80sp,#-1]!
 ELSE
	sub z80sp,z80sp,#2
	mov r1,z80sp
	writemem16
 ENDIF
	mov r0,#0x38
	rebasepc

	b DoInterrupt_end

DoInterrupt_mode2
	;@ push pc on stack
	ldr r0,[cpucontext,#z80pc_base]
	sub r0,z80pc,r0
 IF FAST_Z80SP
	mov r1,r0, lsr #8
	strb r1,[z80sp,#-1]!
	strb r0,[z80sp,#-1]!
 ELSE
	sub z80sp,z80sp,#2
	mov r1,z80sp
	writemem16
 ENDIF

	;@ get 1 byte vector address
	ldrb r0,[cpucontext, #z80irqvector]
	ldr r1,[cpucontext, #z80i]
	orr r0,r0,r1,lsr #16

	;@ read new pc from vector address
	stmfd sp!,{r3,r12}
	mov lr,pc
	ldr pc,[cpucontext,#z80_read16]

	;@ rebase new pc
 IF UPDATE_CONTEXT
     str z80pc,[cpucontext,#z80pc_pointer]
 ENDIF
	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	

DoInterrupt_end
	;@ interupt accepted so callback irq interface
	ldr r0,[cpucontext, #z80irqcallback]
	tst r0,r0
	ldmeqfd sp!,{pc}
	stmfd sp!,{r3,r12}
	mov lr,pc
	mov pc,r0    ;@ call callback function
	ldmfd sp!,{r3,r12}
	ldmfd sp!,{pc} ;@ return

 ENDIF

DAATable
      DCW 5
      DCW 256
      DCW 512
      DCW 769

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -