945 lines
10 KiB
C
945 lines
10 KiB
C
|
/**
|
|||
|
* @file mescc.h
|
|||
|
* @brief Runtime library.
|
|||
|
* @author Miguel I. Garcia Lopez / FloppySoftware
|
|||
|
*
|
|||
|
* Runtime library for MESCC (Mike's Enhanced
|
|||
|
* Small C Compiler for Z80 & CP/M).
|
|||
|
*
|
|||
|
* This library file must be included first!
|
|||
|
*
|
|||
|
* Need following EQU's (generated by the compiler):
|
|||
|
* - ccSTACKSIZE : Stack size in bytes.
|
|||
|
*
|
|||
|
* Supports following #defs:
|
|||
|
* - #define CC_STDIO Support for stdin, stdout & stderr.
|
|||
|
* - #define CC_REDIR Support for stdin & stdout redirection
|
|||
|
* in command line (needs CC_STDIO).
|
|||
|
* - #define CC_NO_MUL To exclude MULTIPLICATION code.
|
|||
|
* - #define CC_NO_DIV To exclude DIVISION & MODULUS code.
|
|||
|
* - #define CC_NO_SWITCH To exclude SWITCH code.
|
|||
|
* - #define CC_NO_ARGS To exclude ARGC & ARGV code.
|
|||
|
* - #define CC_NO_ORG To exclude ORG 0100H code.
|
|||
|
*
|
|||
|
* Sets the following #defines:
|
|||
|
*
|
|||
|
* - BYTE
|
|||
|
* - WORD
|
|||
|
* - BOOL
|
|||
|
* - NULL
|
|||
|
* - TRUE
|
|||
|
* - FALSE
|
|||
|
* - SIZEOF_CHAR
|
|||
|
* - SIZEOF_INT
|
|||
|
* - SIZEOF_PTR
|
|||
|
*
|
|||
|
* Revisions:
|
|||
|
* - 16 Jan 2001 : Last revision.
|
|||
|
* - 23 Mar 2007 : Expand ccladr1 and ccladr2 for more speed.
|
|||
|
* - 16 Apr 2007 : GPL'd.
|
|||
|
* - 26 Aug 2012 : Added standard defs.
|
|||
|
* - 08 Dec 2014 : Minor changes.
|
|||
|
* - 09 Dec 2014 : Added support for stdin, stdout & stderr with CC_STDIO.
|
|||
|
* - 12 Dec 2014 : Added support for stdin & stdout redirection in command line with CC_REDIR.
|
|||
|
* - 16 Jan 2015 : Added SIZEOF_??? definitions.
|
|||
|
* - 16 Feb 2015 : Modified / added code in cctmpw, ccxpb2, ccxpb, ccxpb3, ccxpw2
|
|||
|
* ccxpw, ccxpw3, ccladr2sv, ccladr2, ccladr1sv, ccladr1,
|
|||
|
* to avoid use of IX register.
|
|||
|
* - 20 Mar 2015 : Added support for CC_NO_MUL, CC_NO_DIV, CC_NO_SWITCH, CC_NO_ARGS.
|
|||
|
* - 12 Apr 2015 : Removed ccDEFARGS code.
|
|||
|
* - 14 Jul 2015 : Modified code for << and >>, because a shift of 0 positions,
|
|||
|
* resulted in a wrong value (they assumed a shift > 0) - ie: 128 >> 0 resulted in 0.
|
|||
|
* - 19 Oct 2015 : Improved multiplication algorithm (ccmul & ccumul).
|
|||
|
* - 05 Nov 2015 : Modified ccsxt.
|
|||
|
* - 30 Nov 2015 : Added support for atexit().
|
|||
|
* - 24 Jan 2016 : Added support for CC_NO_ORG.
|
|||
|
* - 10 Dec 2016 : Documented. GPL v3.
|
|||
|
*
|
|||
|
* Copyright (c) 1999-2016 Miguel I. Garcia Lopez / FloppySoftware.
|
|||
|
*
|
|||
|
* Licensed under the GNU General Public License v3.
|
|||
|
*
|
|||
|
* http://www.floppysoftware.es
|
|||
|
* floppysoftware@gmail.com
|
|||
|
*/
|
|||
|
|
|||
|
/* STANDARD DEFs
|
|||
|
-------------
|
|||
|
*/
|
|||
|
|
|||
|
#define BYTE unsigned char
|
|||
|
#define WORD unsigned int
|
|||
|
#define BOOL char
|
|||
|
#define NULL 0
|
|||
|
#define TRUE 1
|
|||
|
#define FALSE 0
|
|||
|
|
|||
|
#define SIZEOF_CHAR 1 /* [unsigned] char */
|
|||
|
#define SIZEOF_INT 2 /* [unsigned] int */
|
|||
|
#define SIZEOF_PTR 2 /* pointer */
|
|||
|
|
|||
|
/* RUNTIME CODE
|
|||
|
------------
|
|||
|
*/
|
|||
|
|
|||
|
#ifndef CC_NO_ORG
|
|||
|
|
|||
|
#asm
|
|||
|
; Start at TPA
|
|||
|
|
|||
|
ORG 0100H
|
|||
|
|
|||
|
#endasm
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
#asm
|
|||
|
; Runtime address
|
|||
|
|
|||
|
ccrtadr:
|
|||
|
|
|||
|
; Set stack under BDOS (xx00h)
|
|||
|
|
|||
|
LD HL,(6)
|
|||
|
LD L,0
|
|||
|
LD SP,HL
|
|||
|
|
|||
|
; Leave space for stack and init. variables
|
|||
|
|
|||
|
LD DE,ccSTACKSIZE
|
|||
|
OR A
|
|||
|
SBC HL,DE
|
|||
|
DEC HL
|
|||
|
LD (ccfreelast),HL
|
|||
|
LD DE,ccfreemem
|
|||
|
LD (ccfreefirst),DE
|
|||
|
OR A
|
|||
|
SBC HL,DE
|
|||
|
INC HL
|
|||
|
LD (ccfreebytes),HL
|
|||
|
JR NC,ccargs
|
|||
|
|
|||
|
; Error, no memory for stack
|
|||
|
|
|||
|
LD C,9
|
|||
|
LD DE,ccerrstack
|
|||
|
CALL 5
|
|||
|
JP 0
|
|||
|
|
|||
|
ccerrstack
|
|||
|
DEFB 'Runtime Error - No stack$'
|
|||
|
|
|||
|
; Setup command line arguments
|
|||
|
|
|||
|
ccargs
|
|||
|
|
|||
|
#endasm
|
|||
|
|
|||
|
#ifndef CC_NO_ARGS
|
|||
|
|
|||
|
#asm
|
|||
|
; Copy command line
|
|||
|
|
|||
|
LD HL,81H
|
|||
|
LD DE,ccmdbuf
|
|||
|
LD BC,127
|
|||
|
LDIR
|
|||
|
|
|||
|
LD A,(80H)
|
|||
|
LD B,0
|
|||
|
LD C,A
|
|||
|
LD HL,ccmdbuf
|
|||
|
ADD HL,BC
|
|||
|
LD (HL),0
|
|||
|
|
|||
|
; Init. argc & argv
|
|||
|
|
|||
|
LD DE,cchptr
|
|||
|
LD HL,ccmdbuf - 1
|
|||
|
LD BC,1
|
|||
|
ccspc
|
|||
|
INC HL
|
|||
|
LD A,(HL)
|
|||
|
OR A
|
|||
|
JR Z,ccarg
|
|||
|
CP ' '
|
|||
|
JR Z,ccspc
|
|||
|
LD A,L
|
|||
|
LD (DE),A
|
|||
|
LD A,H
|
|||
|
INC DE
|
|||
|
LD (DE),A
|
|||
|
INC DE
|
|||
|
INC C
|
|||
|
ccpar
|
|||
|
INC HL
|
|||
|
LD A,(HL)
|
|||
|
OR A
|
|||
|
JR Z,ccarg
|
|||
|
CP ' '
|
|||
|
JR NZ,ccpar
|
|||
|
LD (HL),0
|
|||
|
JR ccspc
|
|||
|
|
|||
|
ccarg
|
|||
|
LD HL,cchptr - 2
|
|||
|
PUSH BC ;argc
|
|||
|
PUSH HL ;argv
|
|||
|
#endasm
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef CC_REDIR
|
|||
|
|
|||
|
#asm
|
|||
|
CALL redir ;FIXME - Check errors
|
|||
|
POP DE
|
|||
|
POP BC
|
|||
|
PUSH HL ;argc
|
|||
|
PUSH DE ;argv
|
|||
|
#endasm
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
#asm
|
|||
|
|
|||
|
; Execute program
|
|||
|
|
|||
|
CALL main
|
|||
|
#endasm
|
|||
|
|
|||
|
/**
|
|||
|
* @fn void exit(int code)
|
|||
|
* @brief Exit to CP/M.
|
|||
|
*
|
|||
|
* FixMe: Return code is lost!
|
|||
|
*/
|
|||
|
#asm
|
|||
|
|
|||
|
; Exit to CP/M
|
|||
|
|
|||
|
exit
|
|||
|
NOP ; Patch for atexit() -- 3 bytes.
|
|||
|
NOP
|
|||
|
NOP
|
|||
|
#endasm
|
|||
|
|
|||
|
#ifdef CC_STDIO
|
|||
|
|
|||
|
BYTE *stdin, *stdout, *stderr; /* Sorry, no available FILE here */
|
|||
|
|
|||
|
#asm
|
|||
|
LD HL,(stdin)
|
|||
|
CALL ccflush
|
|||
|
LD HL,(stdout)
|
|||
|
CALL ccflush
|
|||
|
|
|||
|
JP 0
|
|||
|
|
|||
|
ccflush
|
|||
|
LD A,H
|
|||
|
OR L
|
|||
|
RET Z
|
|||
|
PUSH HL
|
|||
|
CALL fclose
|
|||
|
POP BC
|
|||
|
RET
|
|||
|
#endasm
|
|||
|
|
|||
|
#else
|
|||
|
|
|||
|
#asm
|
|||
|
JP 0
|
|||
|
#endasm
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
#asm
|
|||
|
|
|||
|
; Variables for memory functions
|
|||
|
|
|||
|
ccfreefirst
|
|||
|
DEFW 0 ;Adr. first free byte
|
|||
|
ccfreelast
|
|||
|
DEFW 0 ;Adr. last free byte
|
|||
|
ccfreebytes
|
|||
|
DEFW 0 ;Number of free bytes
|
|||
|
|
|||
|
#endasm
|
|||
|
|
|||
|
#ifndef CC_NO_ARGS
|
|||
|
|
|||
|
#asm
|
|||
|
; Variables for command line arguments
|
|||
|
|
|||
|
ccmdbuf
|
|||
|
DEFS 128 ;Command line buffer
|
|||
|
|
|||
|
DEFW ccNULL ;Pointers table for argv
|
|||
|
cchptr
|
|||
|
DEFW ccNULL,ccNULL,ccNULL,ccNULL,ccNULL
|
|||
|
DEFW ccNULL,ccNULL,ccNULL,ccNULL,ccNULL
|
|||
|
DEFW ccNULL,ccNULL,ccNULL,ccNULL,ccNULL
|
|||
|
DEFW ccNULL,ccNULL,ccNULL,ccNULL,ccNULL
|
|||
|
DEFW ccNULL,ccNULL,ccNULL,ccNULL,ccNULL
|
|||
|
|
|||
|
ccNULL
|
|||
|
DEFB 0 ;Null pointer
|
|||
|
#endasm
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
#asm
|
|||
|
|
|||
|
; Basic routines
|
|||
|
|
|||
|
; Call formats to access locals:
|
|||
|
;
|
|||
|
; Format 1: CALL routine
|
|||
|
; DEFB SpOffset
|
|||
|
;
|
|||
|
; Format 2: CALL routine
|
|||
|
; DEFW SpOffset
|
|||
|
|
|||
|
; HL = unsigned char from local (format 2)
|
|||
|
|
|||
|
ccxgb2
|
|||
|
CALL ccladr2
|
|||
|
JR ccxgb3
|
|||
|
|
|||
|
; HL = unsigned char from local (format 1)
|
|||
|
|
|||
|
ccxgb
|
|||
|
CALL ccladr1
|
|||
|
ccxgb3
|
|||
|
LD L,(HL)
|
|||
|
LD H,0
|
|||
|
RET
|
|||
|
|
|||
|
; HL = signed char from local (format 2)
|
|||
|
|
|||
|
ccxgc2
|
|||
|
CALL ccladr2
|
|||
|
JR ccgc
|
|||
|
|
|||
|
; HL = signed char from local (format 1)
|
|||
|
|
|||
|
ccxgc
|
|||
|
CALL ccladr1
|
|||
|
|
|||
|
; HL = signed char from (HL)
|
|||
|
|
|||
|
ccgc
|
|||
|
LD A,(HL)
|
|||
|
|
|||
|
; HL = signed char from A
|
|||
|
|
|||
|
ccsxt
|
|||
|
LD L,A
|
|||
|
RLCA
|
|||
|
SBC A
|
|||
|
LD H,A
|
|||
|
RET
|
|||
|
|
|||
|
; LD H,0
|
|||
|
; LD L,A
|
|||
|
; AND 128
|
|||
|
; RET Z
|
|||
|
; DEC H
|
|||
|
; RET
|
|||
|
|
|||
|
; HL = word from local (format 2)
|
|||
|
|
|||
|
ccxgw2
|
|||
|
CALL ccladr2
|
|||
|
JR ccgw
|
|||
|
|
|||
|
; HL = word from local (format 1)
|
|||
|
|
|||
|
ccxgw
|
|||
|
CALL ccladr1
|
|||
|
|
|||
|
; HL = word from (HL)
|
|||
|
|
|||
|
ccgw
|
|||
|
LD A,(HL)
|
|||
|
INC HL
|
|||
|
LD H,(HL)
|
|||
|
LD L,A
|
|||
|
RET
|
|||
|
|
|||
|
; char local = HL (format 2)
|
|||
|
|
|||
|
ccxpb2
|
|||
|
CALL ccladr2sv
|
|||
|
JR ccxpb3
|
|||
|
|
|||
|
; char local = HL (format 1)
|
|||
|
|
|||
|
ccxpb
|
|||
|
CALL ccladr1sv
|
|||
|
ccxpb3
|
|||
|
LD DE,(cctmpw)
|
|||
|
LD (HL),E
|
|||
|
EX DE,HL
|
|||
|
RET
|
|||
|
|
|||
|
; int/ptr local = HL (format 2)
|
|||
|
|
|||
|
ccxpw2
|
|||
|
CALL ccladr2sv
|
|||
|
JR ccxpw3
|
|||
|
|
|||
|
; int/ptr local = HL (format 1)
|
|||
|
|
|||
|
ccxpw
|
|||
|
CALL ccladr1sv
|
|||
|
ccxpw3
|
|||
|
LD DE,(cctmpw)
|
|||
|
LD (HL),E
|
|||
|
INC HL
|
|||
|
LD (HL),D
|
|||
|
EX DE,HL
|
|||
|
RET
|
|||
|
|
|||
|
; Copy 1 word from HL to (DE)
|
|||
|
|
|||
|
ccpw
|
|||
|
LD A,L
|
|||
|
LD (DE),A
|
|||
|
INC DE
|
|||
|
LD A,H
|
|||
|
LD (DE),A
|
|||
|
RET
|
|||
|
|
|||
|
; Calc. local adress
|
|||
|
|
|||
|
cctmpw DEFW 0
|
|||
|
|
|||
|
ccladr2sv
|
|||
|
LD (cctmpw),HL
|
|||
|
|
|||
|
ccladr2
|
|||
|
POP DE
|
|||
|
POP HL
|
|||
|
LD C,(HL)
|
|||
|
INC HL
|
|||
|
LD B,(HL)
|
|||
|
INC HL
|
|||
|
PUSH HL
|
|||
|
PUSH DE
|
|||
|
LD HL,4
|
|||
|
ADD HL,BC
|
|||
|
ADD HL,SP
|
|||
|
RET
|
|||
|
|
|||
|
ccladr1sv
|
|||
|
LD (cctmpw),HL
|
|||
|
|
|||
|
ccladr1
|
|||
|
POP DE
|
|||
|
POP HL
|
|||
|
LD B,0
|
|||
|
LD C,(HL)
|
|||
|
INC HL
|
|||
|
PUSH HL
|
|||
|
PUSH DE
|
|||
|
LD HL,4
|
|||
|
ADD HL,BC
|
|||
|
ADD HL,SP
|
|||
|
RET
|
|||
|
|
|||
|
; OR HL = HL | DE
|
|||
|
|
|||
|
ccor
|
|||
|
LD A,L
|
|||
|
OR E
|
|||
|
LD L,A
|
|||
|
LD A,H
|
|||
|
OR D
|
|||
|
LD H,A
|
|||
|
RET
|
|||
|
|
|||
|
; XOR HL = HL ^ DE
|
|||
|
|
|||
|
ccxor
|
|||
|
LD A,L
|
|||
|
XOR E
|
|||
|
LD L,A
|
|||
|
LD A,H
|
|||
|
XOR D
|
|||
|
LD H,A
|
|||
|
RET
|
|||
|
|
|||
|
; AND HL = HL & DE
|
|||
|
|
|||
|
ccand
|
|||
|
LD A,L
|
|||
|
AND E
|
|||
|
LD L,A
|
|||
|
LD A,H
|
|||
|
AND D
|
|||
|
LD H,A
|
|||
|
RET
|
|||
|
|
|||
|
; LOGIC OR HL = DE || HL
|
|||
|
|
|||
|
cclgor
|
|||
|
LD A,H
|
|||
|
OR L
|
|||
|
OR D
|
|||
|
OR E
|
|||
|
LD L,A
|
|||
|
RET
|
|||
|
|
|||
|
;LD A,H
|
|||
|
;OR L
|
|||
|
;RET NZ
|
|||
|
;LD A,D
|
|||
|
;OR E
|
|||
|
;RET Z
|
|||
|
;INC L
|
|||
|
;RET
|
|||
|
|
|||
|
; LOGIC AND HL = DE && HL
|
|||
|
|
|||
|
cclgand
|
|||
|
LD A,H
|
|||
|
OR L
|
|||
|
RET Z
|
|||
|
LD A,D
|
|||
|
OR E
|
|||
|
RET NZ
|
|||
|
JP ccfalse
|
|||
|
|
|||
|
; HL = HL == DE
|
|||
|
|
|||
|
cceq
|
|||
|
OR A
|
|||
|
SBC HL,DE
|
|||
|
|
|||
|
; LOGIC NOT HL = !HL
|
|||
|
|
|||
|
cclgnot
|
|||
|
LD A,H
|
|||
|
OR L
|
|||
|
JP NZ,ccfalse
|
|||
|
INC L
|
|||
|
RET
|
|||
|
|
|||
|
; HL = HL != DE
|
|||
|
|
|||
|
ccne
|
|||
|
OR A
|
|||
|
SBC HL,DE
|
|||
|
RET
|
|||
|
|
|||
|
; HL = DE > HL (SIGNED)
|
|||
|
|
|||
|
ccgt
|
|||
|
EX DE,HL
|
|||
|
|
|||
|
; HL = DE < HL (SIGNED)
|
|||
|
|
|||
|
cclt
|
|||
|
CALL cccmp
|
|||
|
RET C
|
|||
|
DEC L
|
|||
|
RET
|
|||
|
|
|||
|
; HL = DE <= HL (SIGNED)
|
|||
|
|
|||
|
ccle
|
|||
|
CALL cccmp
|
|||
|
RET Z
|
|||
|
RET C
|
|||
|
DEC L
|
|||
|
RET
|
|||
|
|
|||
|
; HL = DE >= HL (SIGNED)
|
|||
|
|
|||
|
ccge
|
|||
|
CALL cccmp
|
|||
|
RET NC
|
|||
|
DEC L
|
|||
|
RET
|
|||
|
|
|||
|
; Compare DE with HL, and return: (SIGNED)
|
|||
|
;
|
|||
|
; CARRY if DE < HL
|
|||
|
; ZERO if DE == HL
|
|||
|
; HL = 1
|
|||
|
|
|||
|
cccmp
|
|||
|
LD A,E
|
|||
|
SUB L
|
|||
|
LD E,A
|
|||
|
LD A,D
|
|||
|
SBC H
|
|||
|
LD HL,1
|
|||
|
JP M,cccmp1
|
|||
|
OR E
|
|||
|
RET
|
|||
|
|
|||
|
cccmp1
|
|||
|
OR E
|
|||
|
SCF
|
|||
|
RET
|
|||
|
|
|||
|
; HL = DE <= HL (UNSIGNED)
|
|||
|
|
|||
|
ccule
|
|||
|
CALL ccucmp
|
|||
|
RET Z
|
|||
|
RET C
|
|||
|
DEC L
|
|||
|
RET
|
|||
|
|
|||
|
; HL = DE >= HL (UNSIGNED)
|
|||
|
|
|||
|
ccuge
|
|||
|
CALL ccucmp
|
|||
|
RET NC
|
|||
|
DEC L
|
|||
|
RET
|
|||
|
|
|||
|
; HL = DE > HL (UNSIGNED)
|
|||
|
|
|||
|
ccugt
|
|||
|
EX DE,HL
|
|||
|
|
|||
|
; HL = DE < HL (UNSIGNED)
|
|||
|
|
|||
|
ccult
|
|||
|
CALL ccucmp
|
|||
|
RET C
|
|||
|
DEC L
|
|||
|
RET
|
|||
|
|
|||
|
; Compare DE with HL, and return: (UNSIGNED)
|
|||
|
;
|
|||
|
; CARRY if DE < HL
|
|||
|
; ZERO if DE == HL
|
|||
|
; HL = 1
|
|||
|
|
|||
|
ccucmp
|
|||
|
LD A,D
|
|||
|
CP H
|
|||
|
JR NZ,ccucmp1
|
|||
|
LD A,E
|
|||
|
CP L
|
|||
|
|
|||
|
ccucmp1
|
|||
|
LD HL,1
|
|||
|
RET
|
|||
|
|
|||
|
; HL = DE >> HL (UNSIGNED)
|
|||
|
|
|||
|
ccuasr
|
|||
|
EX DE,HL
|
|||
|
LD A,E
|
|||
|
ccuasr1
|
|||
|
OR A
|
|||
|
RET Z
|
|||
|
DEC A
|
|||
|
SRL H
|
|||
|
RR L
|
|||
|
JR ccuasr1
|
|||
|
|
|||
|
; HL = DE >> HL (ARITMETIC)
|
|||
|
|
|||
|
ccasr
|
|||
|
EX DE,HL
|
|||
|
LD A,E
|
|||
|
ccasr1
|
|||
|
OR A
|
|||
|
RET Z
|
|||
|
DEC A
|
|||
|
SRA H
|
|||
|
RR L
|
|||
|
JR ccasr1
|
|||
|
|
|||
|
; HL = DE << HL (UNSIGNED)
|
|||
|
|
|||
|
ccuasl
|
|||
|
|
|||
|
; HL = DE << HL (ARITMETIC)
|
|||
|
|
|||
|
ccasl
|
|||
|
EX DE,HL
|
|||
|
LD A,E
|
|||
|
ccasl1
|
|||
|
OR A
|
|||
|
RET Z
|
|||
|
DEC A
|
|||
|
ADD HL,HL
|
|||
|
JR ccasl1
|
|||
|
|
|||
|
; HL = DE - HL
|
|||
|
|
|||
|
ccsub
|
|||
|
EX DE,HL
|
|||
|
OR A
|
|||
|
SBC HL,DE
|
|||
|
RET
|
|||
|
|
|||
|
; HL = ~HL (1 COMPLEMENT)
|
|||
|
|
|||
|
cccom
|
|||
|
LD A,H
|
|||
|
CPL
|
|||
|
LD H,A
|
|||
|
LD A,L
|
|||
|
CPL
|
|||
|
LD L,A
|
|||
|
RET
|
|||
|
|
|||
|
; HL = -HL (2 COMPLEMENT)
|
|||
|
|
|||
|
ccneg
|
|||
|
LD A,H
|
|||
|
CPL
|
|||
|
LD H,A
|
|||
|
LD A,L
|
|||
|
CPL
|
|||
|
LD L,A
|
|||
|
INC HL
|
|||
|
RET
|
|||
|
|
|||
|
#endasm
|
|||
|
|
|||
|
#ifndef CC_NO_MUL
|
|||
|
|
|||
|
#asm
|
|||
|
|
|||
|
; HL = DE * HL (UNSIGNED)
|
|||
|
|
|||
|
ccumul
|
|||
|
|
|||
|
; HL = DE * HL (SIGNED)
|
|||
|
|
|||
|
ccmul
|
|||
|
LD A,H
|
|||
|
LD C,L
|
|||
|
LD HL,0
|
|||
|
LD B,16
|
|||
|
ccmul0
|
|||
|
ADD HL,HL
|
|||
|
SLA C
|
|||
|
RL A
|
|||
|
JR NC,ccmul1
|
|||
|
ADD HL,DE
|
|||
|
ccmul1
|
|||
|
DJNZ ccmul0
|
|||
|
RET
|
|||
|
|
|||
|
#endasm
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
#ifndef CC_NO_DIV
|
|||
|
|
|||
|
#asm
|
|||
|
|
|||
|
; HL = DE % HL (SIGNED)
|
|||
|
|
|||
|
ccmod
|
|||
|
CALL ccdiv
|
|||
|
EX DE,HL
|
|||
|
RET
|
|||
|
|
|||
|
; HL = DE / HL (SIGNED)
|
|||
|
; DE = DE % HL (SIGNED)
|
|||
|
|
|||
|
ccdiv
|
|||
|
LD B,H
|
|||
|
LD C,L
|
|||
|
LD A,D
|
|||
|
XOR B
|
|||
|
PUSH AF
|
|||
|
LD A,D
|
|||
|
OR A
|
|||
|
CALL M,ccdivdeneg
|
|||
|
LD A,B
|
|||
|
OR A
|
|||
|
|
|||
|
JP P,ccdiv0
|
|||
|
|
|||
|
LD A,B
|
|||
|
CPL
|
|||
|
LD B,A
|
|||
|
LD A,C
|
|||
|
CPL
|
|||
|
LD C,A
|
|||
|
INC BC
|
|||
|
|
|||
|
ccdiv0
|
|||
|
EX DE,HL
|
|||
|
LD DE,0
|
|||
|
LD A,16
|
|||
|
|
|||
|
ccdiv1
|
|||
|
PUSH AF
|
|||
|
|
|||
|
ADD HL,HL
|
|||
|
|
|||
|
RL E
|
|||
|
RL D
|
|||
|
LD A,D
|
|||
|
OR E
|
|||
|
|
|||
|
JR Z,ccdiv2
|
|||
|
|
|||
|
LD A,E
|
|||
|
SUB C
|
|||
|
LD A,D
|
|||
|
SBC B
|
|||
|
|
|||
|
JP M,ccdiv2
|
|||
|
LD A,L
|
|||
|
OR 1
|
|||
|
LD L,A
|
|||
|
LD A,E
|
|||
|
SUB C
|
|||
|
LD E,A
|
|||
|
LD A,D
|
|||
|
SBC B
|
|||
|
LD D,A
|
|||
|
|
|||
|
ccdiv2
|
|||
|
POP AF
|
|||
|
DEC A
|
|||
|
JR NZ,ccdiv1
|
|||
|
POP AF
|
|||
|
RET P
|
|||
|
|
|||
|
CALL ccneg
|
|||
|
|
|||
|
ccdivdeneg
|
|||
|
LD A,D
|
|||
|
CPL
|
|||
|
LD D,A
|
|||
|
LD A,E
|
|||
|
CPL
|
|||
|
LD E,A
|
|||
|
INC DE
|
|||
|
RET
|
|||
|
|
|||
|
; HL = DE % HL (UNSIGNED)
|
|||
|
|
|||
|
ccumod
|
|||
|
CALL ccudiv
|
|||
|
EX DE,HL
|
|||
|
RET
|
|||
|
|
|||
|
; HL = DE / HL (UNSIGNED)
|
|||
|
; DE = DE % HL (UNSIGNED)
|
|||
|
|
|||
|
ccudiv
|
|||
|
LD (ccudiv_tmp),HL
|
|||
|
LD HL,ccudiv_cnt
|
|||
|
LD (HL),17
|
|||
|
LD BC,0
|
|||
|
PUSH BC
|
|||
|
XOR A
|
|||
|
|
|||
|
ccudiv0
|
|||
|
RL E
|
|||
|
RL D
|
|||
|
DEC (HL)
|
|||
|
POP HL
|
|||
|
JR Z,ccudiv2
|
|||
|
LD A,0
|
|||
|
ADC 0
|
|||
|
ADD HL,HL
|
|||
|
LD B,H
|
|||
|
ADD L
|
|||
|
LD HL,(ccudiv_tmp)
|
|||
|
SUB L
|
|||
|
LD C,A
|
|||
|
LD A,B
|
|||
|
SBC H
|
|||
|
LD B,A
|
|||
|
PUSH BC
|
|||
|
JR NC,ccudiv1
|
|||
|
ADD HL,BC
|
|||
|
EX (SP),HL
|
|||
|
|
|||
|
ccudiv1
|
|||
|
LD HL,ccudiv_cnt
|
|||
|
CCF
|
|||
|
JR ccudiv0
|
|||
|
|
|||
|
ccudiv2
|
|||
|
EX DE,HL
|
|||
|
RET
|
|||
|
|
|||
|
ccudiv_tmp
|
|||
|
DEFW 0
|
|||
|
ccudiv_cnt
|
|||
|
DEFB 0
|
|||
|
|
|||
|
#endasm
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
#ifndef CC_NO_SWITCH
|
|||
|
|
|||
|
#asm
|
|||
|
|
|||
|
; Switch, on entry:
|
|||
|
;
|
|||
|
; DE = Table address
|
|||
|
; HL = Where to go if value was not found in table
|
|||
|
; B = Number of entries in table
|
|||
|
|
|||
|
ccswtch
|
|||
|
EX (SP),HL
|
|||
|
EX DE,HL
|
|||
|
|
|||
|
ccswch1
|
|||
|
LD A,E
|
|||
|
CP (HL)
|
|||
|
INC HL
|
|||
|
JR NZ,ccswch2
|
|||
|
LD A,D
|
|||
|
CP (HL)
|
|||
|
JR NZ,ccswch2
|
|||
|
INC HL
|
|||
|
LD E,(HL)
|
|||
|
INC HL
|
|||
|
LD D,(HL)
|
|||
|
EX DE,HL
|
|||
|
POP BC
|
|||
|
JP (HL)
|
|||
|
|
|||
|
ccswch2
|
|||
|
INC HL
|
|||
|
INC HL
|
|||
|
INC HL
|
|||
|
DJNZ ccswch1
|
|||
|
EX (SP),HL
|
|||
|
POP BC
|
|||
|
JP (HL)
|
|||
|
|
|||
|
#endasm
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
#asm
|
|||
|
|
|||
|
; HL = TRUE
|
|||
|
|
|||
|
cctrue
|
|||
|
LD L,1
|
|||
|
RET
|
|||
|
|
|||
|
; HL = FALSE
|
|||
|
|
|||
|
ccfalse
|
|||
|
LD HL,0
|
|||
|
RET
|
|||
|
|
|||
|
#endasm
|
|||
|
|
|||
|
|