From: Alan Cox Date: Thu, 12 Feb 2015 01:44:16 +0000 (+0000) Subject: z80: banked mode need modified helpers so stick them into the tree X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=5b155dbaa243a7bf6251852396593fcd2b3cb6b0;p=FUZIX.git z80: banked mode need modified helpers so stick them into the tree If upstream SDCC grows banking support we can tidy this back up but for now a more generalised banking setup in SDCC is some ways off --- diff --git a/Kernel/lowlevel-z80-banked.s b/Kernel/lowlevel-z80-banked.s index 219102fc..e650c87d 100644 --- a/Kernel/lowlevel-z80-banked.s +++ b/Kernel/lowlevel-z80-banked.s @@ -583,3 +583,586 @@ __enter_s: ld sp, hl push de ret + +; +; This must be in common in banked builds +; + .globl __sdcc_call_hl + +__sdcc_call_hl: + jp (hl) + +; +; These we stick in common as we use them in many places and +; want to avoid ugly bits. Some are borrowed from sdcc some are +; done differently for cleanliness. They have been modified to be +; banking friendly. +; + + .globl _memset + +_memset: + pop af ; ret + pop iy ; dummy/banking + pop hl ; dest + pop de ; fill + pop bc ; count + push bc + push de + push hl + push iy + push af + + ld a, b + or c + ret z + ld (hl), e + dec a + ret z ; > 1 ? + ld d, h + ld e, l + inc de + dec bc + ldir + ret + +;-------------------------------------------------------------------------- +; divsigned.s +; +; Copyright (C) 2000-2010, Michael Hope, Philipp Klaus Krause +; +; This library is free software; you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by the +; Free Software Foundation; either version 2, or (at your option) any +; later version. +; +; This library is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this library; see the file COPYING. If not, write to the +; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +; MA 02110-1301, USA. +; +; As a special exception, if you link this library with other files, +; some of which are compiled with SDCC, to produce an executable, +; this library does not by itself cause the resulting executable to +; be covered by the GNU General Public License. This exception does +; not however invalidate any other reasons why the executable file +; might be covered by the GNU General Public License. +;-------------------------------------------------------------------------- + +.globl __divsint +.globl __divschar + +__divsint: + pop af + pop bc + pop hl + pop de + push de + push hl + push bc + push af + + jp __div16 + +__divschar: + ld hl, #2+1+2 ; banked + add hl, sp + + ld e, (hl) + dec hl + ld l, (hl) + +__div8:: + ld a, l ; Sign extend + rlca + sbc a,a + ld h, a +__div_signexte:: + ld a, e ; Sign extend + rlca + sbc a,a + ld d, a + ; Fall through to __div16 + + ;; signed 16-bit division + ;; + ;; Entry conditions + ;; HL = dividend + ;; DE = divisor + ;; + ;; Exit conditions + ;; HL = quotient + ;; DE = remainder + ;; + ;; Register used: AF,B,DE,HL +__div16:: + ;; Determine sign of quotient by xor-ing high bytes of dividend + ;; and divisor. Quotient is positive if signs are the same, negative + ;; if signs are different + ;; Remainder has same sign as dividend + ld a, h ; Get high byte of dividend + xor a, d ; Xor with high byte of divisor + rla ; Sign of quotient goes into the carry + ld a, h ; Get high byte of dividend + push af ; Save sign of both quotient and reminder + + ; Take absolute value of dividend + rla + jr NC, .chkde ; Jump if dividend is positive + sub a, a ; Substract dividend from 0 + sub a, l + ld l, a + sbc a, a ; Propagate borrow (A=0xFF if borrow) + sub a, h + ld h, a + + ; Take absolute value of divisor +.chkde: + bit 7, d + jr Z, .dodiv ; Jump if divisor is positive + sub a, a ; Subtract divisor from 0 + sub a, e + ld e, a + sbc a, a ; Propagate borrow (A=0xFF if borrow) + sub a, d + ld d, a + + ; Divide absolute values +.dodiv: + call __divu16 + +.fix_quotient: + ; Negate quotient if it is negative + pop af ; recover sign of quotient + ret NC ; Jump if quotient is positive + ld b, a + sub a, a ; Subtract quotient from 0 + sub a, l + ld l, a + sbc a, a ; Propagate borrow (A=0xFF if borrow) + sub a, h + ld h, a + ld a, b + ret + +;-------------------------------------------------------------------------- +; modmixed.s +; +; Copyright (C) 2010, Philipp Klaus Krause +; +; This library is free software; you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by the +; Free Software Foundation; either version 2, or (at your option) any +; later version. +; +; This library is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this library; see the file COPYING. If not, write to the +; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +; MA 02110-1301, USA. +; +; As a special exception, if you link this library with other files, +; some of which are compiled with SDCC, to produce an executable, +; this library does not by itself cause the resulting executable to +; be covered by the GNU General Public License. This exception does +; not however invalidate any other reasons why the executable file +; might be covered by the GNU General Public License. +;-------------------------------------------------------------------------- + +.globl __moduschar + +__moduschar: + ld hl,#2+1+2 + ld d, h + add hl,sp + + ld e,(hl) + dec hl + ld l,(hl) + + ld a,l ; Sign extend + rlca + sbc a, a + ld h, a + + call __div16 + +__get_remainder:: + ; Negate remainder if it is negative and move it into hl + rla + ex de, hl + ret NC ; Return if remainder is positive + sub a, a ; Subtract remainder from 0 + sub a, l + ld l, a + sbc a, a ; Propagate remainder (A=0xFF if borrow) + sub a, h + ld h, a + ret + + + +;-------------------------------------------------------------------------- +; divunsigned.s +; +; Copyright (C) 2000-2012, Michael Hope, Philipp Klaus Krause, Marco Bodrato +; +; This library is free software; you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by the +; Free Software Foundation; either version 2, or (at your option) any +; later version. +; +; This library is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this library; see the file COPYING. If not, write to the +; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +; MA 02110-1301, USA. +; +; As a special exception, if you link this library with other files, +; some of which are compiled with SDCC, to produce an executable, +; this library does not by itself cause the resulting executable to +; be covered by the GNU General Public License. This exception does +; not however invalidate any other reasons why the executable file +; might be covered by the GNU General Public License. +;-------------------------------------------------------------------------- + + ;; Originally from GBDK by Pascal Felber. + +.globl __divuint +.globl __divuchar + +__divuint: + pop af + pop bc + pop hl + pop de + push de + push hl + push bc + push af + + jr __divu16 + +__divuchar: + ld hl,#2+1+2 + add hl,sp + + ld e,(hl) + dec hl + ld l,(hl) + + ;; Fall through +__divu8:: + ld h,#0x00 + ld d,h + ; Fall through to __divu16 + + ;; unsigned 16-bit division + ;; + ;; Entry conditions + ;; HL = dividend + ;; DE = divisor + ;; + ;; Exit conditions + ;; HL = quotient + ;; DE = remainder + ;; carry = 0 + ;; If divisor is 0, quotient is set to "infinity", i.e HL = 0xFFFF. + ;; + ;; Register used: AF,B,DE,HL +__divu16:: + ;; Two algorithms: one assumes divisor <2^7, the second + ;; assumes divisor >=2^7; choose the applicable one. + ld a,e + and a,#0x80 + or a,d + jr NZ,.morethan7bits + ;; Both algorithms "rotate" 24 bits (H,L,A) but roles change. + + ;; unsigned 16/7-bit division +.atmost7bits: + ld b,#16 ; bits in dividend and possible quotient + ;; Carry cleared by AND/OR, this "0" bit will pass trough HL.[*] + adc hl,hl +.dvloop7: + ;; HL holds both dividend and quotient. While we shift a bit from + ;; MSB of dividend, we shift next bit of quotient in from carry. + ;; A holds remainder. + rla + + ;; If remainder is >= divisor, next bit of quotient is 1. We try + ;; to compute the difference. + sub a,e + jr NC,.nodrop7 ; Jump if remainder is >= dividend + add a,e ; Otherwise, restore remainder + ;; The add above sets the carry, because sbc a,e did set it. +.nodrop7: + ccf ; Complement borrow so 1 indicates a + ; successful substraction (this is the + ; next bit of quotient) + adc hl,hl + djnz .dvloop7 + ;; Carry now contains the same value it contained before + ;; entering .dvloop7[*]: "0" = valid result. + ld e,a ; DE = remainder, HL = quotient + ret + +.morethan7bits: + ld b,#9 ; at most 9 bits in quotient. + ld a,l ; precompute the first 7 shifts, by + ld l,h ; doing 8 + ld h,#0 + rr l ; undoing 1 +.dvloop: + ;; Shift next bit of quotient into bit 0 of dividend + ;; Shift next MSB of dividend into LSB of remainder + ;; A holds both dividend and quotient. While we shift a bit from + ;; MSB of dividend, we shift next bit of quotient in from carry + ;; HL holds remainder + adc hl,hl ; HL < 2^(7+9), no carry, ever. + + ;; If remainder is >= divisor, next bit of quotient is 1. We try + ;; to compute the difference. + sbc hl,de + jr NC,.nodrop ; Jump if remainder is >= dividend + add hl,de ; Otherwise, restore remainder + ;; The add above sets the carry, because sbc hl,de did set it. +.nodrop: + ccf ; Complement borrow so 1 indicates a + ; successful substraction (this is the + ; next bit of quotient) + rla + djnz .dvloop + ;; Take care of the ninth quotient bit! after the loop B=0. + rl b ; BA = quotient + ;; Carry now contains "0" = valid result. + ld d,b + ld e,a ; DE = quotient, HL = remainder + ex de,hl ; HL = quotient, DE = remainder + ret + +;-------------------------------------------------------------------------- +; modunsigned.s +; +; Copyright (C) 2009-2010, Philipp Klaus Krause +; +; This library is free software; you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by the +; Free Software Foundation; either version 2, or (at your option) any +; later version. +; +; This library is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this library; see the file COPYING. If not, write to the +; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +; MA 02110-1301, USA. +; +; As a special exception, if you link this library with other files, +; some of which are compiled with SDCC, to produce an executable, +; this library does not by itself cause the resulting executable to +; be covered by the GNU General Public License. This exception does +; not however invalidate any other reasons why the executable file +; might be covered by the GNU General Public License. +;-------------------------------------------------------------------------- + +.globl __moduchar +.globl __moduint + +__moduchar: + ld hl,#2+1+2 + add hl,sp + + ld e,(hl) + dec hl + ld l,(hl) + + call __divu8 + + ex de,hl + + ret + +__moduint: + pop af + pop bc + pop hl + pop de + push de + push hl + push bc + push af + + call __divu16 + + ex de,hl + + ret + +;-------------------------------------------------------------------------- +; mulchar.s +; +; Copyright (C) 2000, Michael Hope +; +; Modified for banking 2015 Alan Cox +; +; This library is free software; you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by the +; Free Software Foundation; either version 2, or (at your option) any +; later version. +; +; This library is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this library; see the file COPYING. If not, write to the +; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +; MA 02110-1301, USA. +; +; As a special exception, if you link this library with other files, +; some of which are compiled with SDCC, to produce an executable, +; this library does not by itself cause the resulting executable to +; be covered by the GNU General Public License. This exception does +; not however invalidate any other reasons why the executable file +; might be covered by the GNU General Public License. +;-------------------------------------------------------------------------- + +.globl __mulint + +__mulint: + pop af + pop bc + pop hl + pop de + push de + push hl + push bc + push af + + ;; Fall through + + ;; Parameters: + ;; hl, de (left, right irrelevant) + ld b,h + ld c,l + + ;; 16-bit multiplication + ;; + ;; Entry conditions + ;; bc = multiplicand + ;; de = multiplier + ;; + ;; Exit conditions + ;; hl = less significant word of product + ;; + ;; Register used: AF,BC,DE,HL +__mul16:: + xor a,a + ld l,a + or a,b + ld b,#16 + + ;; Optimise for the case when this side has 8 bits of data or + ;; less. This is often the case with support address calls. + jr NZ,2$ + ld b,#8 + ld a,c +1$: + ;; Taken from z88dk, which originally borrowed from the + ;; Spectrum rom. + add hl,hl +2$: + rl c + rla ;DLE 27/11/98 + jr NC,3$ + add hl,de +3$: + djnz 1$ + ret + + +;-------------------------------------------------------------------------- +; memmove.s +; +; Copyright (C) 2008-2009, Philipp Klaus Krause, Marco Bodrato +; +; This library is free software; you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by the +; Free Software Foundation; either version 2, or (at your option) any +; later version. +; +; This library is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this library; see the file COPYING. If not, write to the +; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +; MA 02110-1301, USA. +; +; As a special exception, if you link this library with other files, +; some of which are compiled with SDCC, to produce an executable, +; this library does not by itself cause the resulting executable to +; be covered by the GNU General Public License. This exception does +; not however invalidate any other reasons why the executable file +; might be covered by the GNU General Public License. +;-------------------------------------------------------------------------- + + .globl _memmove + .globl _memcpy + +; The Z80 has the ldir and lddr instructions, which are perfect for implementing memmove(). + +_memcpy: +_memmove: + pop af + pop iy + pop hl + pop de + pop bc + push bc + push de + push hl + push iy + push af + ld a, c + or a, b + ret Z + push hl + sbc hl, de ; or above cleared carry. + add hl, de ; same carry as the line before + jr C, memmove_up +memmove_down: + dec bc + add hl, bc + ex de, hl + add hl, bc + inc bc + lddr + pop hl + ret +memmove_up: + ex de, hl + ldir + pop hl + ret +