summaryrefslogtreecommitdiff
path: root/z180
diff options
context:
space:
mode:
Diffstat (limited to 'z180')
-rw-r--r--z180/Tupfile4
-rw-r--r--z180/cpuinfo.180204
2 files changed, 208 insertions, 0 deletions
diff --git a/z180/Tupfile b/z180/Tupfile
index c7d79fb..0c3f95e 100644
--- a/z180/Tupfile
+++ b/z180/Tupfile
@@ -2,6 +2,7 @@ include_rules
PROG = hdrom
CFBOOT = cfboot
+CPUINFO = cpuinfo
SRC = init.180
SRC += ddtz.180
@@ -52,6 +53,9 @@ rm -f ${OUTPUT}; exit ${ERROR} \
: $(CFBOOT).180 |> $(AS) -%B/HFS |> %B.hex | %B.lst
: $(CFBOOT).hex |> srec_cat -o %o -c_array %B -C_COMpressed -include %f -Intel |> $(CFBOOT).c | $(CFBOOT).h
+: $(CPUINFO).180 |> $(AS) -%B/HFS |> %B.hex | %B.lst
+: $(CPUINFO).hex |> srec_cat -o %o -c_array %B -C_COMpressed -include %f -Intel |> $(CPUINFO).c | $(CPUINFO).h
+
#COMMAND="$(AS) -%B/$(AS_OPT)"; \
diff --git a/z180/cpuinfo.180 b/z180/cpuinfo.180
new file mode 100644
index 0000000..8629aa5
--- /dev/null
+++ b/z180/cpuinfo.180
@@ -0,0 +1,204 @@
+ .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