// Standard library for ccz80 version 2.0.7
// Febraury 2012

function register word strlen(word)
{
  "            ld   de,-1                     ",
  "__strlen_1:                                ",
  "            ld   a,(hl)                    ",
  "            inc  de                        ",
  "            inc  hl                        ",
  "            or   a                         ",
  "            jr   nz,__strlen_1             ",
  "            ex   de,hl ; HL = string lenght",
  "            ret                            "
}

function word strcpy(word, word)
{
  "            ld   hl,2                                      ",
  "            add  hl,sp                                     ",
  "            ld   c,(hl)                                    ",
  "            inc  hl                                        ",
  "            ld   b,(hl) ; BC = 2nd parameter               ",
  "            inc  hl                                        ",
  "            ld   e,(hl)                                    ",
  "            inc  hl                                        ",
  "            ld   d,(hl) ; DE = 1st parameter               ",
  "__strcpy_0:             ; Entry point for another functions",
  "            ld   h,d                                       ",
  "            ld   l,e    ; HL = 1st parameter copy          ",
  "__strcpy_1:                                                ",
  "            ld   a,(bc)                                    ",
  "            ld   (de),a                                    ",
  "            inc  de                                        ",
  "            inc  bc                                        ",
  "            or   a                                         ",
  "            jr   nz,__strcpy_1                             ",
  "            ret                                            "
}

function word strncpy(word, word, word)
{
  "             ld   hl,2                                             ",
  "             add  hl,sp                                            ",
  "             ld   c,(hl)                                           ",
  "             inc  hl                                               ",
  "             ld   b,(hl)        ; BC = 3td parameter               ",
  "             inc  hl                                               ",
  "             ld   e,(hl)                                           ",
  "             inc  hl                                               ",
  "             ld   d,(hl)        ; DE = 2nd parameter               ",
  "             inc  hl                                               ",
  "             ld   a,(hl)                                           ",
  "             inc  hl                                               ",
  "             ld   h,(hl)                                           ",
  "             ld   l,a           ; HL = 1st parameter               ",
  "__strncpy_0:                    ; Entry point for another functions",
  "             push hl                                               ",
  "__strncpy_1:                                                       ",
  "             ld   a,b                                              ",
  "             or   c                                                ",
  "             jr   z,__strncpy_2 ; All characters copied            ",
  "             ld   a,(de)                                           ",
  "             or   a                                                ",
  "             jr   z,__strncpy_2 ; Found end in source string       ",
  "             ld   (hl),a                                           ",
  "             inc  hl                                               ",
  "             inc  de                                               ",
  "             dec  bc                                               ",
  "             jr   __strncpy_1   ; Start loop                       ",
  "__strncpy_2:                                                       ",
  "             ld   (hl),0                                           ",
  "             pop  hl                                               ",
  "             ret                                                   "
}

function word strcat(word, word)
{
  "            ld   hl,2                              ",
  "            add  hl,sp                             ",
  "            ld   c,(hl)                            ",
  "            inc  hl                                ",
  "            ld   b,(hl) ; BC = 2nd parameter       ",
  "            inc  hl                                ",
  "            ld   e,(hl)                            ",
  "            inc  hl                                ",
  "            ld   d,(hl) ; DE = 1st parameter       ",
  "__strcat_0: ; Entry for another functions          ",
  "            ld   h,d                               ",
  "            ld   l,e    ; HL = 1st parameter copy  ",
  "__strcat_1:                                        ",
  "            ld   a,(de)                            ",
  "            inc  de                                ",
  "            or   a                                 ",
  "            jr   nz,__strcat_1                     ",
  "            dec  de     ; DE = final zero character",
  "__strcat_2:                                        ",
  "            ld   a,(bc)                            ",
  "            ld   (de),a                            ",
  "            inc  de                                ",
  "            inc  bc                                ",
  "            or   a                                 ",
  "            jr   nz,__strcat_2                     ",
  "            ret                                    "
}

function word strset(word, byte, word)
{
  "            ld   hl,2                           ",
  "            add  hl,sp                          ",
  "            ld   c,(hl)                         ",
  "            inc  hl                             ",
  "            ld   b,(hl) ; BC = 3th parameter    ",
  "            inc  hl                             ",
  "            inc  hl                             ",
  "            ld   d,(hl) ; D = 2nd parameter     ",
  "            inc  hl                             ",
  "            ld   a,(hl)                         ",
  "            inc  hl                             ",
  "            ld   h,(hl)                         ",
  "            ld   l,a    ; HL = 1st parameter    ",
  "__strset_0: ; Entry point for another funcions  ",
  "            push hl     ; Save string address   ",
  "__strset_1:                                     ",
  "            ld   a,b                            ",
  "            or   c                              ",
  "            jr   z,__strset_2                   ",
  "            ld   (hl),d                         ",
  "            inc  hl                             ",
  "            dec  bc                             ",
  "            jr   __strset_1                     ",
  "__strset_2:                                     ",
  "            ld   (hl),0                         ",
  "            pop  hl     ; Restore string address",
  "            ret                                 "
}

function word strltrm(word, byte)
{
  "             ld   hl,3                                                               ",
  "             add  hl,sp                                                              ",
  "             ld   b,(hl) ; B = 2nd parameter                                         ",
  "             inc  hl                                                                 ",
  "             ld   e,(hl)                                                             ",
  "             inc  hl                                                                 ",
  "             ld   d,(hl) ; DE = 1st parameter                                        ",
  "             ld   h,d                                                                ",
  "             ld   l,e    ; HL = 1st parameter copy                                   ",
  "             push hl                                                                 ",
  "             push hl     ; Save string address (2 times)                             ",
  "__strltrm_1:                                                                         ",
  "             ld   a,(hl)                                                             ",
  "             cp   b                                                                  ",
  "             inc  hl                                                                 ",
  "             jr   z,__strltrm_1                                                      ",
  "             dec  hl     ; HL = pointer to first character not equal to 2nd parameter",
  "             pop  de     ; Restore string address                                    ",
  "__strltrm_2:                                                                         ",
  "             ld   a,(hl)                                                             ",
  "             ld   (de),a                                                             ",
  "             inc  de                                                                 ",
  "             inc  hl                                                                 ",
  "             or   a                                                                  ",
  "             jr   nz,__strltrm_2                                                     ",
  "             pop  hl     ; Restore string address                                    ",
  "             ret                                                                     "
}

function word strrtrm(word, byte)
{
  "             ld   hl,3                                                       ",
  "             add  hl,sp                                                      ",
  "             ld   b,(hl) ; B = 2nd parameter                                 ",
  "             inc  hl                                                         ",
  "             ld   e,(hl)                                                     ",
  "             inc  hl                                                         ",
  "             ld   d,(hl) ; DE = 1st parameter                                ",
  "             ld   h,d                                                        ",
  "             ld   l,e    ; HL = 1st parameter copy                           ",
  "             push hl     ; Save string address                               ",
  "             dec  hl     ; HL = pointer to previous first character of string",
  "__strrtrm_1:                                                                 ",
  "             ld   a,(de)                                                     ",
  "             or   a                                                          ",
  "             jr   z,__strrtrm_3                                              ",
  "             cp   b                                                          ",
  "             jr   z,__strrtrm_2                                              ",
  "             ld   h,d                                                        ",
  "             ld   l,e                                                        ",
  "__strrtrm_2:                                                                 ",
  "             inc  de                                                         ",
  "             jr   __strrtrm_1                                                ",
  "__strrtrm_3:                                                                 ",
  "             inc  hl                                                         ",
  "             ld   (hl),0                                                     ",
  "             pop  hl     ; Restore string address                            ",
  "             ret                                                             "
}

function word strlpad(word, word, byte)
{
  "             ld   hl,3                                                                                               ",
  "             add  hl,sp                                                                                              ",
  "             ld   a,(hl)                                                                                             ",
  "             ld   (__strlpad_6),a  ; Store 3th parameter                                                             ",
  "             inc  hl                                                                                                 ",
  "             ld   e,(hl)                                                                                             ",
  "             inc  hl                                                                                                 ",
  "             ld   d,(hl)           ; DE = 2nd parameter                                                              ",
  "             inc  hl                                                                                                 ",
  "             ld   a,(hl)                                                                                             ",
  "             inc  hl                                                                                                 ",
  "             ld   h,(hl)                                                                                             ",
  "             ld   l,a              ; HL = 1st parameter                                                              ",
  "             ld   (__strlpad_5),hl ; Store string address                                                            ",
  "             ex   de,hl            ; DE = string address, HL = lenght request                                        ",
  "             add  hl,de            ; HL = pointer to new string end                                                  ",
  "             ld   bc,0             ; Initialize characters to move counter                                           ",
  "__strlpad_1:                                                                                                         ",
  "             inc  bc                                                                                                 ",
  "             ld   a,(de)                                                                                             ",
  "             or   a                                                                                                  ",
  "             jr   z,__strlpad_2                                                                                      ",
  "             inc  de                                                                                                 ",
  "             jr   __strlpad_1                                                                                        ",
  "__strlpad_2:                                                                                                         ",
  "             push de               ; Save pointer to string end                                                      ",
  "             push hl               ; Save pointer to new string end                                                  ",
  "             ex   de,hl                                                                                              ",
  "             or   a                                                                                                  ",
  "             sbc  hl,de                                                                                              ",
  "             pop  de               ; Restore pointer to new string end                                               ",
  "             pop  hl               ; Restore pointer to string end                                                   ",
  "             jr   nc,__strlpad_4   ; Lenght request < string lenght                                                  ",
  "             lddr                                                                                                    ",
  "             ex   de,hl            ; DE = pointer to previous string start, HL = pointer to previous new string start",
  "             or   a                                                                                                  ",
  "             sbc  hl,de            ; HL = lenght to pad                                                              ",
  "             ld   de,(__strlpad_5) ; Restore string address                                                          ",
  "             ld   a,(__strlpad_6)                                                                                    ",
  "             ld   b,a              ; B = pad character                                                               ",
  "             ex   de,hl            ; DE = lenght to pad, HL = pointer to space to pad                                ",
  "__strlpad_3:                                                                                                         ",
  "             ld   (hl),b                                                                                             ",
  "             inc  hl                                                                                                 ",
  "             dec  de                                                                                                 ",
  "             ld   a,d                                                                                                ",
  "             or   e                                                                                                  ",
  "             jr   nz,__strlpad_3                                                                                     ",
  "__strlpad_4:                                                                                                         ",
  "             ld   hl,(__strlpad_5) ; Restore string address                                                          ",
  "             ret                                                                                                     ",
  "__strlpad_5: defw 0                ; String address                                                                  ",
  "__strlpad_6: defb 0                ; Pad character                                                                   "
}

function word strrpad(word, word, byte)
{
  "             ld   hl,3                                           ",
  "             add  hl,sp                                          ",
  "             ld   d,(hl)        ; D = 3th parameter              ",
  "             inc  hl                                             ",
  "             ld   c,(hl)                                         ",
  "             inc  hl                                             ",
  "             ld   b,(hl)        ; BC = 2nd parameter             ",
  "             inc  hl                                             ",
  "             ld   a,(hl)                                         ",
  "             inc  hl                                             ",
  "             ld   h,(hl)                                         ",
  "             ld   l,a           ; HL = 1st parameter             ",
  "             push hl            ; Save string address            ",
  "__strrpad_1:                                                     ",
  "             ld   a,b                                            ",
  "             or   c                                              ",
  "             jr   z,__strrpad_3 ; Lenght request <= string lenght",
  "             ld   a,(hl)                                         ",
  "             or   a                                              ",
  "             jr   z,__strrpad_2 ; End string                     ",
  "             inc  hl                                             ",
  "             dec  bc                                             ",
  "             jr   __strrpad_1                                    ",
  "__strrpad_2:                                                     ",
  "             ld   (hl),d                                         ",
  "             inc  hl                                             ",
  "             dec  bc                                             ",
  "             ld   a,b                                            ",
  "             or   c                                              ",
  "             jr   nz,__strrpad_2                                 ",
  "             ld   (hl),0                                         ",
  "__strrpad_3:                                                     ",
  "             pop  hl            ; Restore string address         ",
  "             ret                                                 "
}

function register word strupr(word)
{
  "            push hl           ; Save string address   ",
  "__strupr_1:                                           ",
  "            ld   a,(hl)                               ",
  "            or   a                                    ",
  "            jr   z,__strupr_3 ; End string            ",
  "            cp   \"a\"                                ",
  "            jr   c,__strupr_2                         ",
  "            cp   \"z\"+1                              ",
  "            jr   nc,__strupr_2                        ",
  "            sub  \"a\"-\"A\"                          ",
  "            ld   (hl),a                               ",
  "__strupr_2:                                           ",
  "            inc  hl                                   ",
  "            jr   __strupr_1   ; Next character        ",
  "__strupr_3:                                           ",
  "            pop  hl           ; Restore string address",
  "            ret                                       "
}

function register word strlwr(word)
{
  "            push hl           ; Save string address   ",
  "__strlwr_1:                                           ",
  "            ld   a,(hl)                               ",
  "            or   a                                    ",
  "            jr   z,__strlwr_3 ; End string            ",
  "            cp   \"A\"                                ",
  "            jr   c,__strlwr_2                         ",
  "            cp   \"Z\"+1                              ",
  "            jr   nc,__strlwr_2                        ",
  "            add  a,\"a\"-\"A\"                        ",
  "            ld   (hl),a                               ",
  "__strlwr_2:                                           ",
  "            inc  hl                                   ",
  "            jr   __strlwr_1   ; Next character        ",
  "__strlwr_3:                                           ",
  "            pop  hl           ; Restore string address",
  "            ret                                       "
}

function byte strcmp(word, word)
{
  "            ld   hl,2                                 ",
  "            add  hl,sp                                ",
  "            ld   c,(hl)                               ",
  "            inc  hl                                   ",
  "            ld   b,(hl)       ; BC = 2nd parameter    ",
  "            inc  hl                                   ",
  "            ld   e,(hl)                               ",
  "            inc  hl                                   ",
  "            ld   d,(hl)                               ",
  "            ex   de,hl        ; HL = 1st parameter    ",
  "__strcmp_1:                                           ",
  "            ld   a,(bc)                               ",
  "            or   (hl)                                 ",
  "            ret  z            ; Strings are identical ",
  "            ld   a,(bc)                               ",
  "            cp   (hl)                                 ",
  "            inc  hl                                   ",
  "            inc  bc                                   ",
  "            jr   z,__strcmp_1 ; Identical characters  ",
  "            ld   a,1          ; First string is least ",
  "            ret  nc                                   ",
  "            inc  a            ; Second string is least",
  "            ret                                       "
}

function word strchr(word, byte)
{
  "            ld   hl,3                              ",
  "            add  hl,sp                             ",
  "            ld   b,(hl)       ; B = 2nd parameter  ",
  "            inc  hl                                ",
  "            ld   e,(hl)                            ",
  "            inc  hl                                ",
  "            ld   d,(hl)                            ",
  "            ex   de,hl        ; HL = 1st parameter ",
  "__strchr_1:                                        ",
  "            ld   a,(hl)                            ",
  "            or   a                                 ",
  "            jr   z,__strchr_2 ; character not found",
  "            cp   b                                 ",
  "            ret  z            ; character found    ",
  "            inc  hl                                ",
  "            jr   __strchr_1                        ",
  "__strchr_2:                                        ",
  "            ld   hl,0                              ",
  "            ret                                    "
}

function word strstr(word, word)
{
  "            ld   hl,2                                             ",
  "            add  hl,sp                                            ",
  "            ld   e,(hl)                                           ",
  "            inc  hl                                               ",
  "            ld   d,(hl)       ; DE = 2nd parameter                ",
  "            inc  hl                                               ",
  "            ld   a,(hl)                                           ",
  "            inc  hl                                               ",
  "            ld   h,(hl)                                           ",
  "            ld   l,a          ; HL = 1st parameter                ",
  "__strstr_1:                                                       ",
  "            ld   a,(hl)                                           ",
  "            or   a                                                ",
  "            jr   z,__strstr_4 ; End 1st string                    ",
  "            push hl           ; Save 1st string pointer           ",
  "            push de           ; Save 2nd string start             ",
  "__strstr_2:                                                       ",
  "            ld   a,(de)                                           ",
  "            or   a                                                ",
  "            jr   z,__strstr_3 ; End 2nd string                    ",
  "            cp   (hl)                                             ",
  "            inc  hl                                               ",
  "            inc  de                                               ",
  "            jr   z,__strstr_2                                     ",
  "__strstr_3:                                                       ",
  "            pop  de           ; Restore 2nd string start          ",
  "            pop  hl           ; Restore 1st string pointer        ",
  "            ret  z            ; 2nd string found in 1st string    ",
  "            inc  hl                                               ",
  "            jr   __strstr_1                                       ",
  "__strstr_4:                                                       ",
  "            ld   hl,0         ; 2nd string not found in 1st string",
  "            ret                                                   "
}

function word btoa(word, byte)
{
  "          ld   hl,3                                ",
  "          add  hl,sp                               ",
  "          ld   a,(hl) ; A = 2nd parameter          ",
  "          inc  hl                                  ",
  "          ld   e,(hl)                              ",
  "          inc  hl                                  ",
  "          ld   d,(hl)                              ",
  "          ex   de,hl  ; HL = 1st parameter         ",
  "__btoa_0:             ; Entry for another functions",
  "          push hl     ; Save string start          ",
  "          ld   b,-100                              ",
  "          call __btoa_1                            ",
  "          ld   b,-10                               ",
  "          call __btoa_1                            ",
  "          add  a,\"0\"                             ",
  "          ld   (hl),a                              ",
  "          inc  hl                                  ",
  "          ld   (hl),0                              ",
  "          pop  hl     ; Restore string start       ",
  "          ret                                      ",
  "__btoa_1:                                          ",
  "          ld   c,\"0\"-1                           ",
  "__btoa_2:                                          ",
  "          inc  c                                   ",
  "          add  a,b                                 ",
  "          jr   c,__btoa_2                          ",
  "          sub  b                                   ",
  "          ld   (hl),c                              ",
  "          inc  hl                                  ",
  "          ret                                      "
}

function word btoh(word, byte)
{
  "          ld   hl,3                                ",
  "          add  hl,sp                               ",
  "          ld   b,(hl) ; B = 2nd paraemter          ",
  "          inc  hl                                  ",
  "          ld   e,(hl)                              ",
  "          inc  hl                                  ",
  "          ld   d,(hl) ; DE = 1st parameter         ",
  "__btoh_0:             ; Entry for another functions",
  "          ld   h,d                                 ",
  "          ld   l,e    ; HL = 1st parameter copy    ",
  "          ld   a,b                                 ",
  "          srl  a                                   ",
  "          srl  a                                   ",
  "          srl  a                                   ",
  "          srl  a                                   ",
  "          call __btoh_1                            ",
  "          ld   a,b                                 ",
  "          and  #0F                                 ",
  "          call __btoh_1                            ",
  "          xor  a                                   ",
  "          ld   (de),a                              ",
  "          ret                                      ",
  "__btoh_1:                                          ",
  "          cp   10                                  ",
  "          jr   c,__btoh_2                          ",
  "          add  a,\"A\"-\"9\"-1                     ",
  "__btoh_2:                                          ",
  "          add  a,\"0\"                             ",
  "          ld   (de),a                              ",
  "          inc  de                                  ",
  "          ret                                      "
}

function word bton(word, byte)
{
  "          ld   hl,3                           ",
  "          add  hl,sp                          ",
  "          ld   a,(hl) ; A = 2nd paraemter     ",
  "          inc  hl                             ",
  "          ld   e,(hl)                         ",
  "          inc  hl                             ",
  "          ld   d,(hl)                         ",
  "          ex   de,hl  ; HL = 1st parameter    ",
  "          push hl     ; Save string address   ",
  "          ld   b,8                            ",
  "__bton_1:                                     ",
  "          rlca                                ",
  "          ld   c,\"0\"                        ",
  "          jr   nc,__bton_2                    ",
  "          inc  c                              ",
  "__bton_2:                                     ",
  "          ld   (hl),c                         ",
  "          inc  hl                             ",
  "          djnz __bton_1                       ",
  "          ld   (hl),0                         ",
  "          pop  hl     ; Restore string address",
  "          ret                                 "
}

function word wtoa(word, word)
{
  "          ld   hl,2                                   ",
  "          add  hl,sp                                  ",
  "          ld   e,(hl)                                 ",
  "          inc  hl                                     ",
  "          ld   d,(hl) ; DE = 2nd parameter            ",
  "          inc  hl                                     ",
  "          ld   a,(hl)                                 ",
  "          inc  hl                                     ",
  "          ld   h,(hl)                                 ",
  "          ld   l,a    ; HL = 1st parameter            ",
  "          ex   de,hl  ; DE = string result, HL = value",
  "__wtoa_0:             ; Entry for another functions   ",
  "          push de     ; Save result string address    ",
  "          ld   bc,-10000                              ",
  "          call __wtoa_1                               ",
  "          ld   bc,-1000                               ",
  "          call __wtoa_1                               ",
  "          ld   bc,-100                                ",
  "          call __wtoa_1                               ",
  "          ld   c,-10                                  ",
  "          call __wtoa_1                               ",
  "          ld   a,l                                    ",
  "          add  a,\"0\"                                ",
  "          ld   (de),a                                 ",
  "          inc  de                                     ",
  "          xor  a                                      ",
  "          ld   (de),a                                 ",
  "          pop  hl     ; Restore result string address ",
  "          ret                                         ",
  "__wtoa_1:                                             ",
  "          ld   a,\"0\"-1                              ",
  "__wtoa_2:                                             ",
  "          inc  a                                      ",
  "          add  hl,bc                                  ",
  "          jr   c,__wtoa_2                             ",
  "          sbc  hl,bc                                  ",
  "          ld   (de),a                                 ",
  "          inc  de                                     ",
  "          ret                                         "
}

function word wtoh(word, word)
{
  "ld   hl,2                            ",
  "add  hl,sp                           ",
  "ld   c,(hl)                          ",
  "inc  hl                              ",
  "ld   b,(hl) ; BC = 2nd parameter     ",
  "inc  hl                              ",
  "ld   e,(hl)                          ",
  "inc  hl                              ",
  "ld   d,(hl) ; DE = 1st parameter     ",
  "ld   h,d                             ",
  "ld   l,e    ; HL = 1st parameter copy",
  "call __btoh_0                        ",
  "ld   b,c                             ",
  "call __btoh_0                        ",
  "dec  hl                              ",
  "dec  hl     ; Restore string address ",
  "ret                                  "
}
using btoh;

function word wton(word, word)
{
  "          ld   hl,2                                           ",
  "          add  hl,sp                                          ",
  "          ld   e,(hl)                                         ",
  "          inc  hl                                             ",
  "          ld   d,(hl) ; DE = 2nd parameter                    ",
  "          inc  hl                                             ",
  "          ld   a,(hl)                                         ",
  "          inc  hl                                             ",
  "          ld   h,(hl)                                         ",
  "          ld   l,a    ; HL = 1st parameter                    ",
  "          ex   de,hl  ; DE = 1st parameter, HL = 2nd parameter",
  "          push de                                             ",
  "          ld   b,16                                           ",
  "__wton_1:                                                     ",
  "          add  hl,hl                                          ",
  "          ld   a,\"0\"                                        ",
  "          jr   nc,__wton_2                                    ",
  "          inc  a                                              ",
  "__wton_2:                                                     ",
  "          ld   (de),a                                         ",
  "          inc  de                                             ",
  "          djnz __wton_1                                       ",
  "          xor  a                                              ",
  "          ld   (de),a                                         ",
  "          pop  hl     ; restore string address                ",
  "          ret                                                 "
}

function register byte atob(word)
{
  "          ld   de,0         ; Digits counter                ",
  "__atob_1:                                                   ",
  "          ld   a,(hl)                                       ",
  "          cp   \"0\"                                        ",
  "          jr   c,__atob_2                                   ",
  "          cp   \"9\"+1                                      ",
  "          jr   nc,__atob_2                                  ",
  "          inc  de                                           ",
  "          inc  hl                                           ",
  "          jr   __atob_1                                     ",
  "__atob_2:                                                   ",
  "          xor  a                                            ",
  "          ld   (__atob_7),a ; Initialize result             ",
  "          inc  a                                            ",
  "          ld   (__atob_8),a ; Initialize weight             ",
  "__atob_3:                                                   ",
  "          ld   a,d                                          ",
  "          or   e                                            ",
  "          jr   z,__atob_4                                   ",
  "          dec  hl                                           ",
  "          ld   a,(__atob_8)                                 ",
  "          ld   b,a          ; B = weight                    ",
  "          ld   a,(hl)                                       ",
  "          sub  \"0\"                                        ",
  "          call __atob_5                                     ",
  "          ld   b,a          ; B = digit value * weight      ",
  "          ld   a,(__atob_7)                                 ",
  "          add  a,b                                          ",
  "          ld   (__atob_7),a ; Result += digit value * weight",
  "          ld   a,(__atob_8)                                 ",
  "          ld   b,10                                         ",
  "          call __atob_5                                     ",
  "          ld   (__atob_8),a ; Weight *= 10                  ",
  "          dec  de                                           ",
  "          jr   __atob_3                                     ",
  "__atob_4:                                                   ",
  "          ld   a,(__atob_7)                                 ",
  "          ret                                               ",
  "__atob_5:                                                   ",
  "          ld   c,a                                          ",
  "          ld   a,b                                          ",
  "          or   a                                            ",
  "          ret  z                                            ",
  "          xor  a                                            ",
  "__atob_6:                                                   ",
  "          add  a,c                                          ",
  "          djnz __atob_6                                     ",
  "          ret                                               ",
  "__atob_7: defb 0            ; Result                        ",
  "__atob_8: defb 0            ; Weight                        "
}

function register byte htob(word)
{
  "           ld   de,0          ; Digits counter                ",
  "__htob_1:                                                     ",
  "           ld   a,(hl)                                        ",
  "           cp   \"0\"                                         ",
  "           jr   c,__htob_3                                    ",
  "           cp   \"9\"+1                                       ",
  "           jr   c,__htob_2                                    ",
  "           cp   \"A\"                                         ",
  "           jr   c,__htob_3                                    ",
  "           cp   \"F\"+1                                       ",
  "           jr   nc,__htob_3                                   ",
  "__htob_2:                                                     ",
  "           inc  de                                            ",
  "           inc  hl                                            ",
  "           jr   __htob_1                                      ",
  "__htob_3:                                                     ",
  "           xor  a                                             ",
  "           ld   (__htob_9),a  ; Initialize result             ",
  "           inc  a                                             ",
  "           ld   (__htob_10),a ; Initialize weight             ",
  "__htob_4:                                                     ",
  "           ld   a,d                                           ",
  "           or   e                                             ",
  "           jr   z,__htob_8                                    ",
  "           dec  hl                                            ",
  "           ld   a,(__htob_10)                                 ",
  "           ld   b,a           ; B = weight                    ",
  "           ld   a,(hl)                                        ",
  "           sub  \"0\"                                         ",
  "           cp   10                                            ",
  "           jr   c,__htob_5                                    ",
  "           sub  \"A\"-\"9\"-1                                 ",
  "__htob_5:                                                     ",
  "           ld   c,a                                           ",
  "           ld   a,b                                           ",
  "           or   a                                             ",
  "           jr   z,__htob_7                                    ",
  "           xor  a                                             ",
  "__htob_6:                                                     ",
  "           add  a,c                                           ",
  "           djnz __htob_6                                      ",
  "__htob_7:                                                     ",
  "           ld   b,a           ; B = digit value * weight      ",
  "           ld   a,(__htob_9)                                  ",
  "           add  a,b                                           ",
  "           ld   (__htob_9),a  ; Result += digit value * weight",
  "           ld   a,(__htob_10)                                 ",
  "           rlca                                               ",
  "           rlca                                               ",
  "           rlca                                               ",
  "           rlca                                               ",
  "           ld   (__htob_10),a ; Weight *= 10                  ",
  "           dec  de                                            ",
  "           jr   __htob_4                                      ",
  "__htob_8:                                                     ",
  "           ld   a,(__htob_9)                                  ",
  "           ret                                                ",
  "__htob_9:  defb 0             ; Result                        ",
  "__htob_10: defb 0             ; Weight                        "
}

function register byte ntob(word)
{
  "          ld   bc,0     ; Digits counter                         ",
  "__ntob_1:                                                        ",
  "          ld   a,(hl)                                            ",
  "          cp   \"0\"                                             ",
  "          jr   c,__ntob_2                                        ",
  "          cp   \"1\"+1                                           ",
  "          jr   nc,__ntob_2                                       ",
  "          inc  bc                                                ",
  "          inc  hl                                                ",
  "          jr   __ntob_1                                          ",
  "__ntob_2:                                                        ",
  "          ld   de,#0001 ; D = 0 as result, E = 1 as weight       ",
  "          ex   de,hl    ; DE = string pointer, HL = result/height",
  "__ntob_3:                                                        ",
  "          ld   a,b                                               ",
  "          or   c                                                 ",
  "          jr   z,__ntob_5                                        ",
  "          dec  de                                                ",
  "          ld   a,(de)                                            ",
  "          cp   \"0\"                                             ",
  "          jr   z,__ntob_4                                        ",
  "          ld   a,h                                               ",
  "          add  a,l                                               ",
  "          ld   h,a      ; Result += weight                       ",
  "__ntob_4:                                                        ",
  "          sla  l        ; Weight *= 2                            ",
  "          dec  bc                                                ",
  "          jr   __ntob_3                                          ",
  "__ntob_5:                                                        ",
  "          ld   a,h                                               ",
  "          ret                                                    "
}

function register word atow(word)
{
  "          ld   bc,0          ; Digits counter                ",
  "__atow_1:                                                    ",
  "          ld   a,(hl)                                        ",
  "          cp   \"0\"                                         ",
  "          jr   c,__atow_2                                    ",
  "          cp   \"9\"+1                                       ",
  "          jr   nc,__atow_2                                   ",
  "          inc  bc                                            ",
  "          inc  hl                                            ",
  "          jr   __atow_1                                      ",
  "__atow_2:                                                    ",
  "          ld   de,0                                          ",
  "          ex   de,hl         ; DE = string pointer, HL = 0   ",
  "          ld   (__atow_7),hl ; Initialize result             ",
  "          inc  hl                                            ",
  "          ld   (__atow_8),hl ; Initialize weight             ",
  "__atow_3:                                                    ",
  "          ld   a,b                                           ",
  "          or   c                                             ",
  "          jr   z,__atow_4                                    ",
  "          dec  de                                            ",
  "          push bc            ; Save counter                  ",
  "          push de            ; Save pointer                  ",
  "          ld   a,(de)                                        ",
  "          sub  \"0\"                                         ",
  "          ld   d,0                                           ",
  "          ld   e,a           ; DE = digit value              ",
  "          ld   hl,(__atow_8)                                 ",
  "          call __atow_5                                      ",
  "          ex   de,hl         ; DE = digit value * weight     ",
  "          ld   hl,(__atow_7)                                 ",
  "          add  hl,de                                         ",
  "          ld   (__atow_7),hl ; Result *= digit value * weight",
  "          ld   hl,(__atow_8)                                 ",
  "          ld   de,10                                         ",
  "          call __atow_5                                      ",
  "          ld   (__atow_8),hl ; Weight *= 10                  ",
  "          pop  de            ; Restore pointer               ",
  "          pop  bc            ; Restore counter               ",
  "          dec  bc                                            ",
  "          jr   __atow_3                                      ",
  "__atow_4:                                                    ",
  "          ld   hl,(__atow_7)                                 ",
  "          ret                                                ",
  "__atow_5:                                                    ",
  "          ld   b,h                                           ",
  "          ld   c,l                                           ",
  "          ld   hl,0                                          ",
  "__atow_6:                                                    ",
  "          ld   a,d                                           ",
  "          or   e                                             ",
  "          ret  z                                             ",
  "          add  hl,bc                                         ",
  "          dec  de                                            ",
  "          jr   __atow_6                                      ",
  "__atow_7: defw 0             ; Result                        ",
  "__atow_8: defw 0             ; Weight                        "
}

function register word htow(word)
{
  "           ld   bc,0           ; Digits counter                ",
  "__htow_1:                                                      ",
  "           ld   a,(hl)                                         ",
  "           cp   \"0\"                                          ",
  "           jr   c,__htow_3                                     ",
  "           cp   \"9\"+1                                        ",
  "           jr   c,__htow_2                                     ",
  "           cp   \"A\"                                          ",
  "           jr   c,__htow_3                                     ",
  "           cp   \"F\"+1                                        ",
  "           jr   nc,__htow_3                                    ",
  "__htow_2:                                                      ",
  "           inc  bc                                             ",
  "           inc  hl                                             ",
  "           jr   __htow_1                                       ",
  "__htow_3:                                                      ",
  "           ld   de,0                                           ",
  "           ex   de,hl          ; DE = string pointer, HL = 0   ",
  "           ld   (__htow_9),hl  ; Initialize result             ",
  "           inc  hl                                             ",
  "           ld   (__atow_10),hl ; Initialize weight             ",
  "__htow_4:                                                      ",
  "           ld   a,b                                            ",
  "           or   c                                              ",
  "           jr   z,__htow_8                                     ",
  "           dec  de                                             ",
  "           push bc             ; Save counter                  ",
  "           push de             ; Save pointer                  ",
  "           ld   a,(de)                                         ",
  "           sub  \"0\"                                          ",
  "           cp   10                                             ",
  "           jr   c,__htow_5                                     ",
  "           sub  \"A\"-\"9\"-1                                  ",
  "__htow_5:                                                      ",
  "           ld   d,0                                            ",
  "           ld   e,a            ; DE = digit value              ",
  "           ld   bc,(__atow_10)                                 ",
  "           ld   hl,0                                           ",
  "__htow_6:                                                      ",
  "           ld   a,d                                            ",
  "           or   e                                              ",
  "           jr   z,__htow_7                                     ",
  "           add  hl,bc                                          ",
  "           dec  de                                             ",
  "           jr   __htow_6                                       ",
  "__htow_7:                                                      ",
  "           ex   de,hl          ; DE = digit value * weight     ",
  "           ld   hl,(__htow_9)                                  ",
  "           add  hl,de                                          ",
  "           ld   (__htow_9),hl  ; Result *= digit value * weight",
  "           ld   hl,(__atow_10)                                 ",
  "           add  hl,hl                                          ",
  "           add  hl,hl                                          ",
  "           add  hl,hl                                          ",
  "           add  hl,hl                                          ",
  "           ld   (__atow_10),hl ; Weight *= 16                  ",
  "           pop  de             ; Restore pointer               ",
  "           pop  bc             ; Restore counter               ",
  "           dec  bc                                             ",
  "           jr   __htow_4                                       ",
  "__htow_8:                                                      ",
  "           ld   hl,(__htow_9)                                  ",
  "           ret                                                 ",
  "__htow_9:  defw 0              ; Result                        ",
  "__atow_10: defw 0              ; Weight                        "
}

function register word ntow(word)
{
  "          ld   bc,0          ; Digits counter             ",
  "__ntow_1:                                                 ",
  "          ld   a,(hl)                                     ",
  "          cp   \"0\"                                      ",
  "          jr   c,__ntow_2                                 ",
  "          cp   \"1\"+1                                    ",
  "          jr   nc,__ntow_2                                ",
  "          inc  bc                                         ",
  "          inc  hl                                         ",
  "          jr   __ntow_1                                   ",
  "__ntow_2:                                                 ",
  "          ld   de,0                                       ",
  "          ex   de,hl         ; DE = string pointer, HL = 0",
  "          ld   (__ntow_6),hl ; Initialize result          ",
  "          inc  hl                                         ",
  "          ld   (__ntow_7),hl ; Initialize weight          ",
  "__ntow_3:                                                 ",
  "          ld   a,b                                        ",
  "          or   c                                          ",
  "          jr   z,__ntow_5                                 ",
  "          dec  de                                         ",
  "          ld   a,(de)                                     ",
  "          push de            ; Save pointer               ",
  "          ld   de,(__ntow_7)                              ",
  "          cp   \"0\"                                      ",
  "          jr   z,__ntow_4                                 ",
  "          ld   hl,(__ntow_6)                              ",
  "          add  hl,de                                      ",
  "          ld   (__ntow_6),hl ; Result += weight           ",
  "__ntow_4:                                                 ",
  "          ex   de,hl         ; HL = weight                ",
  "          pop  de            ; Restore pointer            ",
  "          add  hl,hl                                      ",
  "          ld   (__ntow_7),hl ; Weight *= 2                ",
  "          dec  bc                                         ",
  "          jr   __ntow_3                                   ",
  "__ntow_5:                                                 ",
  "          ld   hl,(__ntow_6)                              ",
  "          ret                                             ",
  "__ntow_6: defw 0             ; Result                     ",
  "__ntow_7: defw 0             ; Weight                     "
}

function register byte toupper(byte)
{
  "cp   \"a\"      ",
  "ret  c          ",
  "cp   \"z\"+1    ",
  "ret  nc         ",
  "sub  \"a\"-\"A\"",
  "ret             "
}

function register byte tolower(byte)
{
  "cp   \"A\"        ",
  "ret  c            ",
  "cp   \"Z\"+1      ",
  "ret  nc           ",
  "add  a,\"a\"-\"A\"",
  "ret               "
}

function inline byte srand(word)
{
  "ld   (_rand+1),hl"
}
using rand;

function word rand()
{
  "          ld   de,0        ",
  "          ld   a,d         ",
  "          ld   h,e         ",
  "          ld   l,253       ",
  "          or   a           ",
  "          sbc  hl,de       ",
  "          sbc  a,0         ",
  "          sbc  hl,de       ",
  "          ld   d,0         ",
  "          sbc  a,d         ",
  "          ld   e,a         ",
  "          sbc  hl,de       ",
  "          jr   nc,__rand_1 ",
  "          inc  hl          ",
  "__rand_1:                  ",
  "          ld   (_rand+1),hl",
  "          ret              "
}

function inline word previousrand()
{
  "ld   hl,(_rand+1)"
} using rand;

function inline byte in(word)
{
  "ld   b,h  ",
  "ld   c,l  ",
  "in   a,(c)"
}

function byte out(word, byte)
{
  "ld   hl,3                       ",
  "add  hl,sp                      ",
  "ld   a,(hl) ; A = 2nd parameter ",
  "inc  hl                         ",
  "ld   c,(hl)                     ",
  "inc  hl                         ",
  "ld   b,(hl) ; BC = 1st parameter",
  "out  (c),a                      ",
  "ret                             "
}

function inline byte absb(byte)
{
  "bit  7,a   ; Test A sign          ",
  "jr   z,$+3 ; Jump if A is positive",
  "neg        ; Change sign of A     "
}

function inline word absw(word)
{
  "bit  7,h   ; Test HL sign          ",
  "jr   z,$+8 ; Jump if HL is positive",
  "ld   de,0                          ",
  "ex   de,hl                         ",
  "or   a                             ",
  "sbc  hl,de ; Change sign of HL     "
}

function register byte sgnb(byte)
{
  "          or   a                                    ",
  "          ret  z          ; Return 0 if value is 0  ",
  "          rlca            ; Test sign               ",
  "          jr   c,__sgnb_1 ; Jump if sign is negative",
  "          ld   a,1        ; Sign is positive        ",
  "          ret                                       ",
  "__sgnb_1:                                           ",
  "          ld   a,-1       ; Sign is negative        ",
  "          ret                                       "
}

function register word sgnw(word)
{
  "          ld   a,h                                  ",
  "          or   l                                    ",
  "          ret  z          ; Return 0 if value is 0  ",
  "          bit  7,h        ; Test sign               ",
  "          jr   z,__sgnw_1 ; Jump if sign is positive",
  "          ld   hl,-1      ; Sign is negative        ",
  "          ret                                       ",
  "__sgnw_1:                                           ",
  "          ld   hl,1       ; Sign is positive        ",
  "          ret                                       "
}

function word min(word, word)
{
  "         ld   hl,2                                                    ",
  "         add  hl,sp                                                   ",
  "         ld   e,(hl)                                                  ",
  "         inc  hl                                                      ",
  "         ld   d,(hl)     ; DE = 2nd value                             ",
  "         inc  hl                                                      ",
  "         ld   a,(hl)                                                  ",
  "         inc  hl                                                      ",
  "         ld   h,(hl)                                                  ",
  "         ld   l,a        ; HL = 1st value                             ",
  "         or   a                                                       ",
  "         sbc  hl,de                                                   ",
  "         jr   nc,__min_1 ; Jump if second value is equal or the lowest",
  "         add  hl,de      ; Restore first value                        ",
  "         ret             ; First value is the lowest                  ",
  "__min_1:                                                              ",
  "         ex   de,hl      ; HL = second value, the lowest              ",
  "         ret             ; Second value is the lowest                 "
}

function word max(word, word)
{
  "         ld   hl,2                                                   ",
  "         add  hl,sp                                                  ",
  "         ld   e,(hl)                                                 ",
  "         inc  hl                                                     ",
  "         ld   d,(hl)    ; DE = 2nd value                             ",
  "         inc  hl                                                     ",
  "         ld   a,(hl)                                                 ",
  "         inc  hl                                                     ",
  "         ld   h,(hl)                                                 ",
  "         ld   l,a       ; HL = 1st value                             ",
  "         or   a                                                      ",
  "         sbc  hl,de                                                  ",
  "         jr   c,__max_1 ; Jump if first value is equal or the largest",
  "         add  hl,de     ; Restore first value                        ",
  "         ret            ; First value is the largest                 ",
  "__max_1:                                                             ",
  "         ex   de,hl     ; HL = second value, the largest             ",
  "         ret            ; Second value is the largest                "
}

function inline byte sqrt(word)
{
  "ld   a,255",
  "ld   de,1 ",
  "inc  a    ",
  "dec  e    ",
  "dec  de   ",
  "add  hl,de",
  "jr   c,$-4"
}

function word power(word, word)
{
  "           ld   hl,2                                              ",
  "           add  hl,sp                                             ",
  "           ld   c,(hl)                                            ",
  "           inc  hl                                                ",
  "           ld   b,(hl)         ; BC = exponent                    ",
  "           ld   a,b                                               ",
  "           or   c                                                 ",
  "           jr   z,__power_4                                       ",
  "           inc  hl                                                ",
  "           ld   a,(hl)                                            ",
  "           inc  hl                                                ",
  "           ld   h,(hl)                                            ",
  "           ld   l,a            ; HL = base                        ",
  "           ld   (__power_5),hl ; Store base                       ",
  "           ld   de,0                                              ",
  "__power_1:                                                        ",
  "           dec  bc                                                ",
  "           ld   a,b                                               ",
  "           or   c                                                 ",
  "           ret  z              ; Exit if exponent counter is 0    ",
  "           ex   de,hl          ; DE = current result to DE, HL = 0",
  "           push bc                                                ",
  "           ld   bc,(__power_5) ; BC = base                        ",
  "           ld   a,16                                              ",
  "__power_2:                                                        ",
  "           srl  b                                                 ",
  "           rr   c                                                 ",
  "           jr   nc,__power_3                                      ",
  "           add  hl,de                                             ",
  "__power_3:                                                        ",
  "           sla  e                                                 ",
  "           rl   d                                                 ",
  "           dec  a                                                 ",
  "           jr   nz,__power_2                                      ",
  "           pop  bc             ; Restore exponent count           ",
  "           jr   __power_1      ; Next product                     ",
  "           ret                                                    ",
  "__power_4:                                                        ",
  "           ld   h,b                                               ",
  "           ld   l,c                                               ",
  "           ret                                                    ",
  "__power_5: defw 0                                                 "
}

function inline word signedword(byte)
{
  "ld   h,0   ",
  "ld   l,a   ",
  "rlca       ",
  "jr   nc,$+3",
  "dec  h     "
}

function inline word endprogram()
{
  "ld   hl,__end_program-1"
}
