.z80 ; for M80, ignored by SLR assembler include z180reg.inc RUN_TPA equ 0 UUNKNOWN equ 0 ;Unknown CPU U8080 equ 1 ;8080 U8085 equ 2 ;8085 UZ80 equ 3 ;Z80 UX180 equ 4 ;HD64180 or higher UHD64180 equ 5 ;HD64180 UZ80180 equ 6 ;Z80180 UZ8S180 equ 7 ;Z8S180, Z8L180 ;------------------------------------------------------------------------------- if RUN_TPA base equ 0100h else base equ 0 endif aseg org base jp start done: db 0 result: db 0 ;------------------------------------------------------------------------------- ; Read internal register at address in L and IOBASE in H. ; reg_in: ld a,h add a,l ld c,a ld b,0 in a,(c) ret ;------------------------------------------------------------------------------- ; Write internal register at address in L and IOBASE in H. ; reg_out: ld b,a ld a,h add a,l ld c,a ld a,b ld b,0 out (c),a ret ;------------------------------------------------------------------------------- ; Check if register C exists. D holds mask of bit to test. ; return nz, if register exists chk_reg: call reg_in cp 0ffh ret nz ; ; check, if register is changeable xor d ; set bit(s) in register to 0 call reg_out call reg_in ; get it back ex af,af' ld a,0ffh ; set to register original state call reg_out ex af,af' cpl and d ret ;------------------------------------------------------------------------------- ; Check CPU ; ; ; return: ; E = 0 Unknown ; E = 1 8080 ; E = 2 8085 ; E = 3 Z80 ; E = 4 HD64180 or higher ; E = 5 HD64180 ; E = 6 Z80180 ; E = 7 Z8S180, Z8L180 ; ;------------------------------------------------------------------------------- ; Registers only in Z180+, not in HD64180 ; 3E OMCR ; ; Registers only in Z8S180/Z8L180 ; 12 ASEXT0 ; 13 ASEXT1 ; 1A ASTC0L ; 1B ASTC0H ; 1C ASTC1L ; 1D ASTC1H ; 1E CMR ; 1F CCR ; 2D IAR1B ; ; Reserved registers ; 11 ; 19 ; 35 ; 37 ; 3B - 3D check: ld e,U8080 ; Init return val, assume 8080 xor a dec a ; 00 --> 0FFH 8080/8085: even parity; Z80+: No overflow jp po,chk_z80 ; Z80+ if P/V flag reset ; The 8085 logical AND instructions always set the auxiliary flag ON. ; The 8080 logical AND instructions set the flag to reflect the ; logical OR of bit 3 of the values involved in the AND operation. ; (8080/8085 ASSEMBLY LANGUAGE PROGRAMMING MANUAL, 1977, 1978) xor a and a ; 8085 sets, 8080 resets half carry. daa ; A=06 (8085) or A=00 (8080) ret z inc e ret chk_z80: ld e,UZ80 ; Assume Z80 daa ; Z80: 099H, x180+: 0F9H cp 99h ; Result on 180 type cpus is F9 here. Thanks Hitachi ret z inc e ; x180 ; At least Hitachi HD64180 ; Test differences in certain internal registers ; to determine the 180 variant. ; First, search the internal register bank. ld h,00H ; I/O Base find_base_loop: ld l,icr call reg_in and 11011111b ; mask I/O Stop bit xor h cp 01FH jr nz,nxt_base ;TODO: additional plausibility checks jr z,base_found nxt_base: ld a,h add a,040H ld h,a jr nc,find_base_loop ret ;I/O registers not found ; Register (base) found. base_found: inc e ; HD64180 ld l,omcr ; Check, if CPU has OMCR register ld d,M_IOC ; call chk_reg ; ret z ; Register does not exist. It's a HD64180 inc e ; Z80180 ld l,cmr ; Check, if CPU has CMR register ld d,M_LNC ; call chk_reg ; ret z ; register does not exist. It's a Z80180 inc e ; S180/L180 (class) detected. ret ;------------------------------------------------------------------------------- start: ld sp,stack call check ld hl,result ld (hl),e dec hl ld (hl),0ffH halt jp $-1 rept 8 dw 0 endm stack: end ; vim:set ts=8 noet nowrap