z80: fix banked di/irqrestore
authorAlan Cox <alan@linux.intel.com>
Mon, 20 Apr 2015 21:24:44 +0000 (22:24 +0100)
committerAlan Cox <alan@linux.intel.com>
Mon, 20 Apr 2015 21:24:44 +0000 (22:24 +0100)
Kernel/lowlevel-z80-banked.s
Kernel/lowlevel-z80-cmos-banked.s [new file with mode: 0644]
Kernel/lowlevel-z80-nmos-banked.s [new file with mode: 0644]

index 992e75a..e23959f 100644 (file)
@@ -576,9 +576,9 @@ _in:
 ;
 
 .ifeq CPU_NMOS_Z80
-       .include "lowlevel-z80-nmos.s"
+       .include "lowlevel-z80-nmos-banked.s"
 .else
-       .include "lowlevel-z80-cmos.s"
+       .include "lowlevel-z80-cmos-banked.s"
 .endif
 
 ;
diff --git a/Kernel/lowlevel-z80-cmos-banked.s b/Kernel/lowlevel-z80-cmos-banked.s
new file mode 100644 (file)
index 0000000..d32c1f5
--- /dev/null
@@ -0,0 +1,22 @@
+               .area _COMMONMEM
+
+               ; IRQ helpers, in common as they may get used by common C
+               ; code (and are tiny)
+
+_di:           ld a, i
+               push af
+               pop hl
+               di
+               ret
+
+_irqrestore:   pop hl          ; sdcc needs to get register arg passing
+               pop de
+               pop af          ; so badly
+               jp po, was_di
+               ei
+               jr irqres_out
+was_di:                di
+irqres_out:    push af
+               push de
+               jp (hl)
+
diff --git a/Kernel/lowlevel-z80-nmos-banked.s b/Kernel/lowlevel-z80-nmos-banked.s
new file mode 100644 (file)
index 0000000..725bc5a
--- /dev/null
@@ -0,0 +1,29 @@
+               .area _COMMONMEM
+
+_di:           xor a           ; NMOS Z80 bug work around as per CPU manual
+               push af
+               pop af          ; clear byte on stack below our usage
+               ld a, i
+               jp pe, was_ei   ; P is now IFF2, if irqs on return is safe
+               dec sp          ; the CPU may have lied due to an erratum
+               dec sp
+               pop af          ; see if anyone pushed a return address
+               and a
+               jr nz, was_ei   ; someone did - IRQs were enabled then
+               scf             ; disabled
+was_ei:                push af
+               pop hl
+               di
+               ret
+
+_irqrestore:   pop hl
+               pop de
+               pop af
+               jr c, was_di
+               ei
+               jr irqres_out
+was_di:                di
+irqres_out:    push af
+               push de
+               jp (hl)
+